MongoDB 查找管道中的数组匹配

Array match in MongoDB lookup pipeline

我有两个 collection。一件艺术品,另一件 collections(多件艺术品的专辑)。 每个作品都有一个“collections”字段,该字段是一个数组,其中保存了它所属的collections的id。

我想做的是获取用户的所有 collection 以及每个 collection 的前 4 幅作品(以在应用程序中显示预览)。

然而,这个本来以为很简单的东西,原来更复杂。

在正常查询中我会这样做:

artworkModel.find({
    collections: collection
})

但是,在聚合管道中,这不起作用,所以我实施的解决方案是:

[
  {$match: {
      author: author,
    },
  },
  {
    $lookup: {
      from: 'artworks',
      as: 'previews',
      let: { collection: '$_id' },
      pipeline: [
        {
          $match: {
            collections: { $exists: true },
            $expr: { $in: ['$$collection', '$collections'] }, 
          },
        },
        { $sort: { date: -1 } },
        { $limit: 4 },
        { $addFields: { id: '$_id' } },
      ],
    },
  }
]

问题是我不能接受这个解决方案,因为与上面的查询不同,它不使用“collections”字段上的索引,因此对 collection.感谢帮助。

编辑:示例数据

作品:

[
    {
      "_id": { "$oid": "612fa9541121d06014e7d9bc" },
      "collections": [
        { "$oid": "612fa9481121d06014e7d9b5" },
        { "$oid": "612fa9f6b2cc520a84e83dde" }
      ],
      "author": { "$oid": "5fe8fe53ff8d9dc25c9e3277" },
      "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vestibulum dolor id justo condimentum ",
      "type": "Text"
    },
    {
      "_id": { "$oid": "60eec90e787a0b320c514446" },
      "author": { "$oid": "5fe8fe53ff8d9dc25c9e3277" },
      "type": "Image",
      "asset": { "$oid": "60eec90e787a0b320c514441" },
      "collections": [{ "$oid": "612fa9f6b2cc520a84e83dde" }]
    },
    {
      "_id": { "$oid": "612fa9f2b2cc520a84e83db1" },
      "collections": [{ "$oid": "612fa9f6b2cc520a84e83dde" }],
      "author": { "$oid": "5fe8fe53ff8d9dc25c9e3277" },
      "text": "Lorem ipsum dolor sit amet",
      "type": "Text"
    },
    {
      "_id": { "$oid": "612549d4778270001862472f" },
      "author": { "$oid": "5fe8fe53ff8d9dc25c9e3277" },
      "type": "Video",
      "asset": { "$oid": "612549d4778270001862472a" }
    }
  ]
  

collections:

[
  {
    "_id": { "$oid": "612fa9f6b2cc520a84e83dde" },
    "name": "Name",
    "author": { "$oid": "5fe8fe53ff8d9dc25c9e3277" },
    "itemsCount": 3,
  }
]

我认为以下查询与您的查询相同。 在 运行 之前,它在 artworks.collections 上创建索引(多键索引)

查询

  • 根据作者过滤集合
  • 使用索引加入正常查找
  • 与 1 个集合进行虚拟连接 [{}] 仅用于应用管道 你想要的,就像一个把戏

如果可以的话请测试一下,然后告诉我它是否有效以及速度是否足够快

Test code here

db.collections.aggregate([
  {
    "$match": {
      "author": {
        "$eq": "5fe8fe53ff8d9dc25c9e3277"
      }
    }
  },
  {
    "$lookup": {
      "from": "artworks",
      "localField": "_id",
      "foreignField": "collections",
      "as": "previews"
    }
  },
  {
    "$lookup": {
      "from": "dummy",
      "let": {
        "previews": "$previews"
      },
      "pipeline": [
        {
          "$set": {
            "previews": "$$previews"
          }
        },
        {
          "$unwind": {
            "path": "$previews"
          }
        },
        {
          "$replaceRoot": {
            "newRoot": "$previews"
          }
        },
        {
          "$sort": {
            "date": -1
          }
        },
        {
          "$limit": 4
        },
        {
          "$set": {
            "id": "$_id"
          }
        },
        {
          "$unset": [
            "_id"
          ]
        }
      ],
      "as": "previews"
    }
  }
])