我有一个看起来像这样的文档。我需要在嵌套数组中更新特定对象的地方。我需要使用名称编辑文本对象,该对象的区域设置为 en 。
[
{
"_id": ObjectId("5e049ebc8e935c407f78c190"),
"source": "homepage",
"url": [
{
"type": "admindsg",
"text": [
{
"locale": "en",
"name": "Admin DSG"
},
{
"locale": "nb",
"name": "Admin DSG"
},
{
"locale": "li",
"name": "Admin DSG"
},
{
"locale": "fi",
"name": "Admin DSG"
}
],
"value": [
{
"locale": "en",
"link": "https://www.facebook.cloud"
},
{
"locale": "nb",
"link": "https://www.facebook.cloud"
},
{
"locale": "li",
"link": "https://www.facebook.cloud"
},
{
"locale": "fi",
"link": "https://www.facebook.cloud"
}
],
"datetime": "2020-02-08 13:36:37"
},
{
"type": "dataauth",
"text": [
{
"locale": "en",
"name": "Data Authorities"
},
{
"locale": "nb",
"name": "Data Authorities"
},
{
"locale": "li",
"name": "Data Authorities"
},
{
"locale": "fi",
"name": "Data Authorities"
}
],
"value": [
{
"locale": "en",
"link": "https://www.facebook.cloud"
},
{
"locale": "nb",
"link": "https://www.facebook.cloud"
},
{
"locale": "li",
"link": "https://www.facebook.cloud"
},
{
"locale": "fi",
"link": "https://www.facebook.cloud"
}
],
"datetime": "2020-02-08 13:36:38"
},
{
"type": "blog",
"text": [
{
"locale": "en",
"name": "facebook blog"
},
{
"locale": "nb",
"name": "facebook blog"
},
{
"locale": "li",
"name": "facebook blog"
},
{
"locale": "fi",
"name": "facebook blog"
}
],
"value": [
{
"locale": "en",
"link": "https://www.facebook.no"
},
{
"locale": "nb",
"link": "https://www.facebook.no"
},
{
"locale": "li",
"link": "https://www.facebook.no"
},
{
"locale": "fi",
"link": "https://www.facebook.no"
}
],
"datetime": "2020-02-08 13:36:39"
},
{
"type": "guide",
"text": [
{
"locale": "en",
"name": "Guidelines for you"
},
{
"locale": "nb",
"name": "Guidelines for you"
},
{
"locale": "li",
"name": "Guidelines for you"
},
{
"locale": "fi",
"name": "Guidelines for you"
}
],
"value": [
{
"locale": "en",
"link": "https://my.instagram.as/"
},
{
"locale": "nb",
"link": "https://my.instagram.as/"
},
{
"locale": "li",
"link": "https://my.instagram.as/"
},
{
"locale": "fi",
"link": "https://my.instagram.as/"
}
],
"datetime": "2020-02-08 13:36:41"
}
]
}
]
完成此任务的最佳方法是什么?
这是我尝试过的查询:
db.getCollection('general').update({
"source": "homepage",
"url.type": "admindsg"
}, {
"$set": {
"url.text.$[elem].name": "YOYO"
}
}, {
"arrayFilters": [{
"elem.locale": {
"$eq": "en"
}
}],
"multi": true
})
这将引发错误:
在路径中找不到标识符“ elem”的数组过滤器 'url.text。$ [elem] .name'
答案 0 :(得分:2)
url
字段是一个数组,因此您需要使用以下语法:
db.getCollection('general').update({
"source": "homepage"
}, {
"$set": {
"url.$[urlId].text.$[textId].name": "YOYO"
}
}, {
"arrayFilters": [
{ "urlId.type": "admindsg" },
{ "textId.locale": "en" },
],
"multi": true
})
答案 1 :(得分:0)
问题是您有2个数组过滤器
url.type = "admindsg"
url.text.local = "en"
您可以使用聚合管道。这将是一种解决方案:
db.getCollection('general').aggregate([
{ $match: { source: "homepage" } },
{ $unwind: "$url" },
{
$set: {
"url.text": {
$cond: {
if: { $eq: ["$url.type", "admindsg"] },
then: {
$reduce: {
input: "$url.text",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[{
$cond: {
if: { $eq: ["$$this.locale", "fi"] },
then: {
$mergeObjects: [
{ locale: "$$this.locale" },
{ name: "Järjestelmänvalvoja DSG" }
]
},
else: "$$this"
}
}]
]
}
}
},
else: "$url.text"
}
}
}
},
{
$group: {
_id: { _id: "$_id", source: "$source" },
url: { $push: "$$ROOT.url" }
}
},
{ $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$_id"] } } }
]).forEach(function (doc) {
db.getCollection('general').updateOne(
{ _id: doc._id },
{ $set: { url: doc.url } }
);
})
您也可以使用$reduce
代替$map
:
{
$set: {
"url.text": {
$cond: {
if: { $eq: ["$url.type", "admindsg"] },
then: {
$map: {
input: "$url.text",
in: {
$cond: {
if: { $eq: [ "$$this.locale", "fi" ] },
then: {
$mergeObjects: [
{ locale: "$$this.locale" },
{ name: "Järjestelmänvalvoja DSG" }
]
},
else: "$$this"
}
}
}
},
else: "$url.text"
}
}
}
},