[MongoDB] Modeling 4.AttributePattern

기훈·2024년 4월 5일

MongoDB

목록 보기
7/28

예측할 수 없는 행동로그 분석하기: 게임과 같은 서비스에서 사용자들의 패턴을 분석하고, 모든 행동을 기록한다.

초기 모델링

  • 유저의 대한 데이터를 생성하고 유저의 로그를 배열로 저장한다

      db.users.insertOne({
        _id: "tom",
        joinDate: new Date(),
        server: "Sevilla",
        job: "merchant",
        logInfo: [],
      });
    
      log = {
        loginTime: new Date(),
        visits: [],
        sails: [],
        trades: [],
        battles: [],
        quests: [],
        fishings: [],
        gambles: [],
        castings: [],
        farmings: [],
      };
    
      log.visits.push({
        location: "Barcelona",
        time: new Date(),
      });
      log.visits.push({
        location: "Sevilla",
        time: new Date(),
      });
      log.visits.push({
        location: "London",
        time: new Date(),
      });
    
      log.trades.push({
        item: "Musket",
        qty: 50,
        price: 1800,
      });
      log.trades.push({
        item: "Musket",
        qty: -50,
        price: 2300,
      });
    
      log.quests.push({
        name: "Cave Invenstigation",
        reward: 50000,
      });
    
      db.users.updateOne(
        { _id: "tom" },
        {
          $addToSet: {
            logInfo: log,
          },
        }
      );
  • 위와 같은 모델링은 하나의 컬렉션에 너무 큰 데이터가 들어가게 된다. (로그가 많아지게 되면 도큐먼트의 최대 크기인 16MB를 초과한다)

개선1

  • 데이터를 분리한다.

    // 어느유저에 대한 로그인지 필드를 추가한다.
    log.user = "tom";
    log.logoutTime = new Date();
    db.logs.insertOne(log);
  • 배열 크기가 문제는 어느정도 해결되었지만, 로그가 추가될 수록 관리가 복잡해지고 인덱스가 많아진다.

개선2

  • key-value 형태로 데이터를 묶고 하나의 인덱스만 생성하여 데이터를 관리한다.
    (어떤형태의 행동이 나오더라도 action의 타입만 정해주고 값과 추가적인 데이터를 추가해주면 더 쉽게 관리할 수 있다)

    // tom이라는 유저의 행동패턴을 actions라는 배열안에 action이라는 key-value 형태로 저장한다.
    date = new Date();
    log = {
    user: "tom",
    loginTime: date,
    logoutTime: new Date(),
    actions: [
      // 액션에 대한 형태를 키밸류로 정의함
      { action: "visit", value: "Barcelona", time: date },
      { action: "visit", value: "Sevilla", time: date },
      { action: "visit", value: "London", time: date },
      { action: "trade", value: "Musket", type: "buy", qty: 50, price: 1800 },
      { action: "trade", value: "Musket", type: "sell", qty: 50, price: 2300 },
      {
        action: "quest",
        value: "Cave Investigation",
        reward: 50000,
        status: "In Progress",
      },
    ],
    };
    
  • 위와 같은 방식은 복합인덱스 형태로 최소한의 인덱스만 설정할 수 있다.

    // 복합인덱스 형태로 인덱스의 개수가 한개로 줄어든다.
    // 특정할 수 있는 필드가 다 제각각(필드가 다양함)인 경우 action이라는 키로 행동을 정의하고 밸류에 데이터를 넣는다.
    db.logs.createIndex({ "actions.action": 1, "actions.value": 1 });
    

결론

  • 특정할 수 있는 필드가 제각각이고, 예측할 수 없는 로그와 같은 데이터는 AttributePattern를 사용해서 모델링을 해보자

0개의 댓글