1

我有一个集合“所有者”,我想返回一个匹配过滤器(任何过滤器)的“所有者”列表,以及该所有者的“宠物”集合中的“宠物”计数,除非我不想要死去的宠物。(编造的例子)

我需要返回的文档看起来与添加了“petCount”字段的“所有者”文档完全一样,因为我正在使用带有 Mongo Java 驱动程序的 Java Pojos。

我使用的 AWS DocumentDB 尚不支持 $lookup 和过滤器。如果是这样,我会使用它并且我会完成:

        db.Owners.aggregate( [
            { $match: {_id: UUID("b13e733d-2686-4266-a686-d3dae6501887")} },
            { $lookup: { from: 'Pets', as: 'pets', 'let': { ownerId: '$_id' }, pipeline: [ { $match: { $expr: { $ne: ['$state', 'DEAD'] } } } ] } },
            { $addFields: { petCount: { $size: '$pets' } } },
            { $project: { pets: 0 } }
        ]).pretty()

但因为它不是我到目前为止得到的:

        db.Owners.aggregate( [
            { $match: {_id: { $in: [ UUID("cbb921f6-50f8-4b0c-833f-934998e5fbff") ] } } },
            { $lookup: { from: 'Pets', localField: '_id', foreignField: 'ownerId', as: 'pets' } },
            { $unwind: { path: '$pets', preserveNullAndEmptyArrays: true } },
            { $match: { 'pets.state': { $ne: 'DEAD' } } },
            { "$group": {
                "_id": "$_id",
                "doc": { "$first": "$$ROOT" },
                "pets": { "$push": "$pets" }
                }
            },
            { $addFields: { "doc.petCount": { $size: '$pets' } } },
            { $replaceRoot: { "newRoot": "$doc" } },
            { $project: { pets: 0 } }
        ]).pretty()

这非常有效,除非所有者只有“死”宠物,否则不会返回所有者,因为所有“文档副本”都被 $match 过滤掉了。当所有文档都为“DEAD”时,我需要使用 petCount = 0 返回父文档。我无法弄清楚如何做到这一点。

有任何想法吗?

这些是 DocDB 4.0 支持的操作https://docs.amazonaws.cn/en_us/documentdb/latest/developerguide/mongo-apis.html

4

1 回答 1

1

编辑:更新以使用$filteraws$reduce文档数据库不支持

您可以使用$filter仅在查找数组中保留非 DEAD 宠物,然后计算剩余数组的大小。

这是Mongo游乐场供您参考。


$减少版本

您可以在聚合管道中使用$reduce来为state.

这是Mongo游乐场供您参考。

于 2021-09-26T01:04:58.383 回答