mongodb中$ nin的非严格行为

时间:2014-04-12 07:31:02

标签: node.js mongodb mongoose aggregation-framework

mongodb中有非严格的$ nin版本吗?例如

假设我们有一个名为User的模型和一个名为task的模型

var TaskSchema = new Schema({
    user_array: [{user: Schema.ObjectId}],
});

快速样本就是这个

task1 : [user1, user2, user4, user7]
task2 : [user2, user 5, user7]

如果我有一个用户列表

[user1, user7]

我想选择user_array中重叠程度最小的任务,在本例中为task2,我知道$ nin严格返回既不包含user1也不包含user7的任务,但我想知道是否有操作在哪里$ nin不严格。

或者,我可以为我写一个DP功能

任何建议都将不胜感激

由于

1 个答案:

答案 0 :(得分:1)

在MongoDB 2.6及更高版本中,您可以使用$setIntersection$size运算符,因此您可以执行.aggregate()语句,如下所示:

db.collection.aggregate([
    { "$project": {
         "user_array": 1,
         "size": { "$size": { 
             "$setIntersection": [ "$user_array", [ "user1", "user7" ] ]
         }}
    }},
    { "$match": { "size": { "$gt": 1 } },
    { "$sort": { "size": 1 }},
    { "$group": {
        "_id": null
        "user_array": { "$first": "$user_array" }
    }}
])

因此,这些运算符有助于减少查找匹配最少的文档所需的步骤。

基本上$setIntersection将数组中的匹配元素返回到与之比较的元素。 $size运算符返回" size"得到的数组。因此,稍后您将使用 $match 过滤掉匹配列表中未找到匹配列表中任何项目的任何文档。

最后,您只需使用"至少"对项目进行排序和退货。匹配。

但是仍然可以在早期版本中完成更多步骤。所以基本上你的"非严格"实现变为$or条件。但是你当然还需要计算比赛数:

db.collection.aggregate([
    { "$project": {
        "_id": { 
            "_id": "$_id",
            "user_array": "$user_array"
        },
        "user_array": 1
    }}
    { "$unwind": "$user_array" },
    { "$match": {
        "$or": [
            { "user_array": "user1" },
            { "user_array": "user7" }
        ]
    }},
    { "$group": {
        "_id": "$_id",
        "size": { "$sum": 1 }
    }},
    { "$sort": { "size": 1 } },
    { "$group": {
        "_id": null,
        "user_array": { "$first": "$_id.user_array" }
    }}
])

这也会做同样的事情。