2014-04-12 28 views
1

mongodb中是否存在非严格的$ nin版本?例如

比方说,我们有一个叫做User模型和模型称为任务

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

一个快速的样品会是这样

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

如果我的用户列表

[user1, user7] 

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

或者,我可以写一个DP功能,这对我来说

任何意见,将不胜感激

感谢

回答

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运算符返回结果数组的“大小”。因此,稍后您可以使用$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" } 
    }} 
]) 

而且这样做会做同样的事情。

+0

感谢,它的工作,虽然我很确定为什么它的工作,目前它返回最重叠的列表,其中包括0重叠,这正是我想要的,但我认为你通过使用'$ gt: 1'选项? – xbd