我在'用户'中有以下文件?集合
{
"_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]。
我做错了什么?
答案 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)
问题是您在一个查询中查询了两个数组:playDates
和matches
。
MongoDB将您的数据放入matches[0]
,因为您的查询与playDates[0]
匹配{"$in":["2014-11-26"]}
,因此MongoDB会将$
绑定到其索引0。
不幸的是,我不知道如何修复它而不删除"playDates":{"$in":["2014-11-26"]}
部分。
答案 2 :(得分:1)
问题是您尝试在单个查询文档中匹配来自两个不同数组的值 - matches
和playDates
。 MongoDB目前不支持此功能。
根据dos:
查询文档应该只包含数组上的单个条件 正在投射的领域。多个条件可能会互相覆盖 内部并导致未定义的行为。
根据这些要求,以下查询不正确:
db.collection.find( { <array>: <value>, <someOtherArray>: <value2> },
{ "<array>.$": 1 } )
由于使用$
来更新其中一个数组中的匹配子文档,导致undefined
行为,解决方法是触发两个查询,一个查找文档,另一个查询在应用程序代码中修改值后更新它。