【问题标题】:Mongoose - find documents based on array of objects field by partial matching another arrayMongoose - 通过部分匹配另一个数组来根据对象数组查找文档
【发布时间】:2018-03-29 21:54:31
【问题描述】:

所以,我会向我的 api 发送以下数组格式

['apple', 'orange', 'mango', 'kiwi', 'lemon']

在我的数据库中,我有一个名为 Recipes 的集合,具有以下字段格式

ingredients: [ { .., name: 'apple', .. }, { .., name: 'orange', .. }] - 具有这种格式的对象数组

在我的数据库中有以下文档:

文档#1

ingredients:[ {.., name: 'apple', ..}, {.., name: 'kiwi', ..}, {.., name: 'banana', ..}]

文档 #2

ingredients:[ {.., name: 'apple', ..}, {.., name: 'orange', ..}, {.., name: 'kiwi', ..}]

文件#3

ingredients:[ {.., name: 'lemon', ..}, {.., name: 'tomato', ..}, {.., name: 'potato', ..}]

mongoose 查询应该如何返回 Document#2、Document#1、Document#3(此顺序是因为它们的数组与初始请求的数组最相似)

【问题讨论】:

    标签: arrays node.js mongodb mongoose


    【解决方案1】:

    您可以使用以下聚合:

    db.collection.aggregate([
        {
            $addFields: {
                totalMatch: {
                    $size: {
                        $setIntersection: [['apple', 'orange', 'mango', 'kiwi', 'lemon'], { $map: { input: "$ingredients", as: "ingredient", in: "$$ingredient.name" } }]
                    }
                }
            }
        },
        {
            $sort: {
                totalMatch: -1
            }
        },
        {
            $project: {
                totalMatch: 0
            }
        }
    ])
    

    您只需要添加额外的字段来计算所有匹配的成分(使用$setIntersection),然后按该字段降序排序。由于您的成分包含对象,您可以使用 $map 仅检索名称。

    【讨论】:

    • 我觉得不错。以及如何处理初始发送数组为空的情况?因为如果是这种情况,我根本不想应用过滤
    • @AndreeaDumitru 澄清一下:您的意思是您不想获取具有空成分数组的文档?
    • 我的意思是,除了['apple', 'orange', 'mango', 'kiwi', 'lemon'],还有可能是一个空数组[]。如果是这种情况,我想在查询开始时以某种方式检查,如果为真则最终跳过过滤
    • 但是你不需要聚合,你可以使用db.collection.find()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2015-01-20
    • 2021-07-08
    • 2021-01-13
    • 2021-12-23
    • 1970-01-01
    • 2019-09-30
    相关资源
    最近更新 更多