【发布时间】:2014-10-08 12:49:30
【问题描述】:
有没有办法根据数组上子文档中的特定键字段有条件地$addToSet?
这是我的意思的一个例子 - 给定由以下示例引导程序生成的集合;
cls
db.so.remove();
db.so.insert({
"Name": "fruitBowl",
"pfms" : [
{
"n" : "apples"
}
]
});
n 定义了一个唯一的文档键。我只希望在任何时候数组中都有一个具有相同n 值的条目。所以我希望能够使用n 更新pfms 数组,这样我就得到了这个;
{
"Name": "fruitBowl",
"pfms" : [
{
"n" : "apples",
"mState": 1111234
}
]
}
这就是我现在的位置;
db.so.update({
"Name": "fruitBowl",
},{
// not allowed to do this of course
// "$pull": {
// "pfms": { n: "apples" },
// },
"$addToSet": {
"pfms": {
"$each": [
{
"n": "apples",
"mState": 1111234
}
]
}
}
}
)
不幸的是,这增加了另一个数组元素;
db.so.find().toArray();
[
{
"Name" : "fruitBowl",
"_id" : ObjectId("53ecfef5baca2b1079b0f97c"),
"pfms" : [
{
"n" : "apples"
},
{
"n" : "apples",
"mState" : 1111234
}
]
}
]
我需要有效地将匹配n 的apples 文档作为唯一标识符,并设置mState 是否已存在条目。很遗憾我不能在同一个文档中使用$pull 和$addToSet(我试过了)。
我在这里真正需要的是字典语义,但现在这不是一个选项,也不是分解文档 - 任何人都可以想出另一种方式吗?
FWIW - 现有格式是语言/驱动程序序列化的结果,我没有准确选择它。
进一步
在我知道数组元素已经存在的情况下,我可以做到这一点;
db.so.update({
"Name": "fruitBowl",
"pfms.n": "apples",
},{
$set: {
"pfms.$.mState": 1111234,
},
}
)
当然只有这样才有效;
- 对于单个数组元素
- 只要我知道它存在
第一个限制不是灾难,但如果我不能有效地将$addToSet 与之前的$set 组合起来(当然我不能),那么这是我能想到的唯一解决方法现在意味着两次数据库往返。
【问题讨论】:
标签: mongodb mongodb-query