Mongodb:按匹配数排序

时间:2014-01-24 15:37:32

标签: arrays mongodb sorting mongoose

我有一个对象数组,我想在MongoDB集合中查询具有与我的对象数组中的任何对象匹配的元素的文档。

例如:

var objects = ["52d58496e0dca1c710d9bfdd", "52d58da5e0dca1c710d9bfde", "52d91cd69188818e3964917b"];

db.scook.recipes.find({products: { $in: objects }}

但是,我想知道我是否可以按MongoDB中的匹配数对结果进行排序。

例如,在顶部将是具有正好三个元素匹配的“配方”:["52d58496e0dca1c710d9bfdd", "52d58da5e0dca1c710d9bfde", "52d91cd69188818e3964917b"]

选择的第二个食谱有两个食谱:["52d58496e0dca1c710d9bfdd", "52d58da5e0dca1c710d9bfde"],第三个只有一个食谱:["52d58496e0dca1c710d9bfdd"]

如果你能得到它拥有的物品数量会很棒。

1 个答案:

答案 0 :(得分:0)

通过使用聚合框架,我认为您应该能够通过以下MongoDB查询获得所需的内容。但是,如果您使用的是Mongoose,则必须将其转换为Mongoose查询。我不确定它是否会完全正常工作,因此您可能需要稍微使用它才能使其正确。此外,这个答案取决于您是否可以使用$or运算符内的$project运算符,并且它将返回true。如果这不起作用,我认为你需要使用map-reduce来获得你需要的东西或服务器端。

db.recipes.aggregate(
    // look for matches
    { $match : { products : { $or : objects }}},
    // break apart documents to by the products subdocuments
    { $unwind : "$products" },
    // search for matches in the sub documents and add productMatch if a match is found
    { $project : {
        desiredField1 : 1,
        desiredField2 : 1,
        products : 1,
        // this may not be a valid comparison, but should hopefully
        // be true or 1 if there is a match
        productMatch : { "$products" : { $or : objects }}
    }},
    // group the unwound documents back together by _id
    { $group : {
        _id : "$_id",
        products : { $push : "$products" },
        // count the matched objects
        numMatches : { $sum : "$productMatch" },
        // increment by 1 for each product
        numProducts : { $sum : 1 }
    }},
    // sort by descending order by numMatches
    { $sort : { numMatches : -1 }}
)