猫鼬提取大文档的特定部分

时间:2018-09-30 17:44:29

标签: mongodb mongoose

对于那些将来迷失于此职位的人。使用的结果仅仅是,mongodb中的4.5mb文档太简单了,无法进行有效的读写。我们想出了一种方法来将文档大小减小到每个文档约0.2mb。 mongo查询需要速度...不要让文档大小超过大约。 0.5mb


我在mongodb中有一小部分文档(大约500个),每个文档为4-6mb。

该数据库用于体育赛事。

该文档的架构如下所示(精简):

const schema = {
  _id: {type: String, default: uuidv1},
  layoutName: String,
  contests: [
    {
      externalId: String,
      thirdPartyEventId: String,
      name: String,
      rounds: [
        {
          _id: {type: String, default: uuidv1},
          thirdPartyId: String,
          externalId: String,
          heats: [
            {
              externalId: String,
              name: String,
              order: Number,
              categories: [
                {
                  key: String,
                  label: String,
                },
              ],
              runs: [
                {
                  thirdPartyId: String,
                  externalId: String,
                  name: String,
                  order: Number,
                },
              ],
            },
          ],
        },
      ],
    },
  ],
}

当前,该应用正在通过_id获取整个对象,然后使用lodash提取热量,但这会花费大量时间(大约400毫秒),因为该文档保存了很多数据。

我试图查看数据库层是否会更快,但是我的mongo查询技巧有些生锈。我将如何使用猫鼬编写查询以提取文档的特定部分。我试图用以下方法查询文档集合:

{
  "_id": "ead08850-c313-11e8-8f9a-f7563bcfbf40",
  "contests.externalId": "Timing1",
  "contests.rounds.externalId": "Timing5",
  "contests.rounds.heats.externalId": "Timing21"
}

但是响应为空。

上面的对象是通往我需要获取的热量的路径。我是否以错误的方式处理此问题?

PS / 当前提取正确的热量:

const contest = find(event.contests, {externalId: contestId})
if (!contest) {
  return false
}
const round = find(contest.rounds, {externalId: roundId})
if (!round) {
  return false
}
return find(round.heats, {externalId: heatId})

1 个答案:

答案 0 :(得分:1)

尝试使用聚合,然后像这样$filter

db.collection.aggregate([
  {
    $match: {
      "_id": 1,
      "contests.rounds.heats.externalId": 5
    }
  },
  {
    $unwind: "$contests"
  },
  {
    $unwind: "$contests.rounds"
  },
  {
    $project: {
      "_id": 0,
      "contests": {
        $filter: {
          input: "$contests.rounds.heats",
          as: "item",
          cond: {
            $eq: ["$$item.externalId", 5]
          }
        }
      }
    }
  }
])

查看working here