gpt4 book ai didi

MongoDB有条件地按特定字段在数组中$addToSet子文档

转载 作者:IT老高 更新时间:2023-10-28 13:15:29 28 4
gpt4 key购买 nike

有没有办法根据数组上子文档中的特定键字段有条件地$addToSet

这是我的意思的一个例子 - 给定由以下示例 Bootstrap 生成的集合;

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,
},
}
)

当然只有这样才有效;

  1. 对于单个数组元素
  2. 只要我知道它存在

第一个限制不是灾难,但如果我不能有效地插入或组合 $addToSet 与以前的 $set (当然我可以' t) 那么我现在能想到的唯一解决方法是两次数据库往返。

最佳答案

$addToSet运算符当然要求“添加到集合”的“整个”文档实际上是唯一的,因此您不能更改文档的“部分”或以其他方式将其视为“部分匹配”。

您偶然发现了使用 $pull 的最佳方法删除任何带有“key”字段的元素,这会导致“重复”,但当然你不能像这样在不同的更新运算符中修改相同的路径。

因此,您将得到的最接近的事情是发出单独的操作,但也可以使用 "Bulk Operations API"这是 MongoDB 2.6 引入的。这允许将两者同时发送到服务器,以获得最接近您将获得的“连续”操作列表的内容:

var bulk = db.so.initializeOrderedBulkOp();

bulk.find({ "Name": "fruitBowl", "pfms.n": "apples": }).updateOne({
"$pull": { "pfms": { "n": "apples" } }
});
bulk.find({ "Name": "fruitBowl" }).updateOne({
"$push": { "pfms": { "n": "apples", "state": 1111234 } }
})

bulk.execute();

如果将元素移动到另一个集合并依赖“upserts”和$set 是不可能或不切实际的,那么这几乎是您最好的方法。为了具有相同的功能,但在集合而不是数组上。

关于MongoDB有条件地按特定字段在数组中$addToSet子文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25315326/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com