MongoDB推送与位置操作员不工作

时间:2014-11-26 22:41:18

标签: node.js mongodb mongodb-query

我在'用户'中有以下文件?集合

{
    "_id" : "388179687996974",
    "matches" : [ 
        {
            "userId" : "1495728740672094",
            "choice" : false,
            "dates" : [],
            "dateId" : null
        }, 
        {
            "userId" : "385516561596016",
            "choice" : true,
            "dates" : [],
            "dateId" : "2014-11-26_385516561596016_388179687996974"
        }, 
        {
            "userId" : "253752728167114",
            "choice" : false,
            "dates" : [],
            "dateId" : null
        }, 
        {
            "userId" : "365296866955687",
            "choice" : null,
            "dates" : [ 
                "2014-11-26"
            ],
            "dateId" : null
        }
    ],
    "playDates" : [ 
        "2014-11-26"
    ]       
}

我有以下查询

db.users.find({
  "_id":{"$ne":"385516561596016"},
  "playDates":{"$in":["2014-11-26"]},
  "matches":{"$elemMatch":{
        "userId":"385516561596016",
        "dates":{"$nin":["2014-11-26"]}}}})

返回上述文件。

我尝试使用位置运算符更新文档,如下所示:

db.users.update({
    "_id":{"$ne":"385516561596016"}, 
    "playDates":{"$in":["2014-11-26"]},
    "matches":{"$elemMatch":{"userId":"385516561596016",
          "dates":{"$nin":["2014-11-26"]}}}}, 
    {"$push":{"matches.$.dates":"2014-11-26"}})

不是将2014-11-26放入userId 385516561596016的匹配中,而是将其放入匹配[0]。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

这闻起来像一个mongodb bug。我尝试了几种不同的变种。

db.items.update({
"_id":{"$ne":"385516561596016"},     
    //without the playDates $in clause
"matches":{"$elemMatch":{"userId":"253752728167114"} } } , 
{"$push":{"matches.$.dates":"test"} } )

这可以按预期工作,将“test”放入第3项。

这不是$ push运算符的错误,因为$ set也搞砸了:

db.items.update({
"_id":{"$ne":"385516561596016"},     
"playDates":{"$in":["2014-11-26"]},
"matches":{"$elemMatch":{"userId":"253752728167114"} } } , 
{"$set":{"matches.$.other":"bob"} } ) 
//fails


db.items.update({
"_id":{"$ne":"385516561596016"},     
"matches":{"$elemMatch":{"userId":"253752728167114"} } } , 
{"$set":{"matches.$.other":"joe"} } )
//success

我认为您应该在JIRA上报告。 https://jira.mongodb.org/secure/Dashboard.jspa(如果你很幸运,他们可能会在一年内修复它。到目前为止,他们已经解决了我的1/8问题。)

与此同时,也许您可​​以更改applogic,以便不需要在playDates中查询$ in?

答案 1 :(得分:1)

问题是您在一个查询中查询了两个数组:playDatesmatches

MongoDB将您的数据放入matches[0],因为您的查询与playDates[0]匹配{"$in":["2014-11-26"]},因此MongoDB会将$绑定到其索引0。

不幸的是,我不知道如何修复它而不删除"playDates":{"$in":["2014-11-26"]}部分。

答案 2 :(得分:1)

问题是您尝试在单个查询文档中匹配来自两个不同数组的值 - matchesplayDates。 MongoDB目前不支持此功能。

根据dos

  

查询文档应该只包含数组上的单个条件   正在投射的领域。多个条件可能会互相覆盖   内部并导致未定义的行为。

     

根据这些要求,以下查询不正确:

 db.collection.find( { <array>: <value>, <someOtherArray>: <value2> },
                    { "<array>.$": 1 } )

由于使用$来更新其中一个数组中的匹配子文档,导致undefined行为,解决方法是触发两个查询,一个查找文档,另一个查询在应用程序代码中修改值后更新它。