想象以下城市记录的集合:
{
"city": "London",
"inhabitants": [
{
"id": "34543534",
"user": {
"name": "Jonathan Deer",
"email": "john@btinternet.com"
}
},
{
"id": "0454534",
"user": {
"name": "Tanya Patel",
"email": "tanya@btinternet.com"
}
},
{
"id": "4345345",
"user": {
"name": "Catherine King",
"email": "catherine@gmail.com"
}
}
]
}
{
"city": "Manchester",
"inhabitants": [
{
"id": "980003",
"user": {
"name": "Benjamin Thaw",
"email": "benny@btinternet.com"
}
},
{
"id": "734488",
"user": {
"name": "Craig Longstone",
"email": "craig@gmail.com"
}
},
{
"id": "4400093",
"user": {
"name": "Arnold Greentree",
"email": "arnold@btinternet.com"
}
},
]
},
我想做的是遍历每个城市的每个居民数组,并查看那里的任何人的电子邮件地址是否包含 btinternet.com 在里面。对于这些用户,我想发送一个新标记 isBT:true ,对于其他所有人(例如gmail.com用户) isBT:false :
"user": {
"name": "Tanya Patel",
"email": "tanya@btinternet.com"
"isBT" true
}
我尝试了以下查询-第一个查询将所有查询都设置为 isBT:false ,第二个查询在电子邮件地址中搜索“ btinternet.com”并设置 isBT:true :
db.city.update({ "inhabitants.user.email": {$exists: true}}, {$set: { "inhabitants.$.user.isBT": false}}, {multi: true})
db.city.update({ "inhabitants.user.email": {$regex: "btinternet.com"}}, {$set: { "inhabitants.$.user.isBT": true}}, {multi: true})
问题在于,当我执行第二个查询时,即使包含必要的“ btinternet.com”电子邮件地址,也会有几条居民记录带有 isBT:false 。似乎只有符合条件的第一条用户记录才被更新... 是否有一种方法可以更新所有“ 居民”阵列的所有用户记录? >
我看过使用位置运算符$ [],但是我们的数据库版本为2.6.3,但是此运算符仅在3.6中引入...
答案 0 :(得分:0)
简短的回答是“否”。
长答案是“不,因为您的MongoDB版本不支持这种操作”。您需要...
1.检索所有匹配的文档,并通过服务器端对数据的处理(例如,使用MongoDB cursor.forEach()
)执行全阵列更新,
2.将您的比赛扩展为"inhabitants.user.isBT": true
(使用
$elemMatch
)并重复执行更新查询,直到
修改后的文档数为0(即不再有数组
要更新的元素),或
3.更新您的MongoDB版本和任何
依赖于当前版本功能的服务器端代码
已在2.6
和3.6
之间更改。
与单个查询相比,任何解决此问题的方法都需要更多的精力。没有解决的办法。吞咽是很难的药,但实际上没有一个很好的选择。