从双嵌套数组5中移除多个不一致的对象



这是另一个挑战:我需要从不正确的对象中清理数据,数组下的对象;包含did, dst和den字段被认为是正确的,@nimrok serok/@rickhg12hs帮助解决了一个工作解决方案,但仍然有一些边缘情况,其中没有对象是有效的,并在更新后保持空数组,所以我想知道这些是否可以在相同的更新查询中清除?

示例文档:

{
"_id": ObjectId("5c05984246a0201286d4b57a"),
f: "x",
"_a": [
{
"_onlineStore": {}
},
{
"_p": {
"pid": 1,
"s": {
"a": {
"t": [
{
id: 1,
"dateP": "20200-09-20",
did: "x",
dst: "y",
den: "z"
},
{
id: 2,
"dateP": "20200-09-20"
}
]
},
"c": {
"t": [
{
id: 3,
"dateP": "20300-09-22"
},
{
id: 4,
"dateP": "20300-09-23",

}
]
}
},
h: "This must stay"
}
},
{
"_p": {
"pid": 2,
"s": {
"a": {
"t": [
{
id: 1,
"dateP": "20200-09-20",

}
]
},
"c": {
"t": [
{
id: 3,
"dateP": "20300-09-22"
},
{
id: 4,
"dateP": "20300-09-23",

}
]
}
},
h: "This must stay"
}
},
{
x: "This must stay"
}
]
}
预期输出:

{
"_a": [
{
"_onlineStore": {}
},
{
"_p": {
"h": "This must stay",
"pid": 1,
"s": {
"a": {
"t": [
{
"dateP": "20200-09-20",
"den": "z",
"did": "x",
"dst": "y",
"id": 1
}
]
}
}
}
},
{
"_p": {
"h": "This must stay",
"pid": 2,
}
},
{
"x": "This must stay"
}
],
"_id": ObjectId("5c05984246a0201286d4b57a"),
"f": "x"
}

操场(正如您在playground示例中看到的,工作几乎完成了,只是在所有数组元素都错误的情况下,数组保持空,因此也需要将其删除…)

mongodb version 4.4

这让我花了一些时间,但这里是为那些面临类似问题的人提供的解决方案:

db.collection.update({},
[
{
"$set": {
_a2: {
$filter: {
input: "$_a",
as: "elem",
cond: {
"$eq": [
{
"$type": "$$elem._p.s"
},
"missing"
]
}
}
},
_a: {
$filter: {
input: "$_a",
as: "elem",
cond: {
"$ne": [
{
"$type": "$$elem._p.s"
},
"missing"
]
}
}
}
}
},
{
"$set": {
"_a": {
"$map": {
"input": "$_a",
"as": "elem",
"in": {
"$mergeObjects": [
"$$elem",
{
"_p": {
"$mergeObjects": [
"$$elem._p",
{
s: {
"$arrayToObject": {
"$map": {
"input": {
"$objectToArray": "$$elem._p.s"
},
"as": "anyKey",
"in": {
"k": "$$anyKey.k",
"v": {
"t": {
"$filter": {
"input": "$$anyKey.v.t",
"as": "t",
"cond": {
"$setIsSubset": [
[
"did",
"dst",
"den"
],
{
"$map": {
"input": {
"$objectToArray": "$$t"
},
"in": "$$this.k"
}
}
]
}
}
}
}
}
}
}
}
}
]
}
}
]
}
}
}
}
},
{
"$set": {
"_a": {
"$map": {
"input": "$_a",
"as": "elem",
"in": {
"$mergeObjects": [
"$$elem",
{
"_p": {
"$mergeObjects": [
"$$elem._p",
{
s: {
"$arrayToObject": {
"$filter": {
"input": {
"$objectToArray": "$$elem._p.s"
},
"as": "anyKey",
"cond": {
$ne: [
"$$anyKey.v.t",
[]
]
}
}
}
}
}
]
}
}
]
}
}
}
}
},
{
"$set": {
"_a": {
"$map": {
"input": "$_a",
"as": "elem",
"in": {
"$mergeObjects": [
"$$elem",
{
"_p": {
"$arrayToObject": {
"$filter": {
"input": {
"$objectToArray": "$$elem._p"
},
"as": "anyKey",
cond: {
$not: {
$in: [
"$$anyKey.v",
[
{}
]
]
}
}
}
}
}
}
]
}
}
}
}
},
{
$set: {
_a: {
"$concatArrays": [
"$_a2",
"$_a"
]
}
}
},
{
$unset: "_a2"
}
])

解释道:

  1. 通过$set/$filter将数组拆分为两个数组,_a2(包含不会更改的元素)和_a(包含受影响的不一致)

  2. $map/$mergeObjects/$mergeObjects/$map/$arrayToObject删除_a中不一致的对象[]._p.s.k.t[]

  3. $map/$mergeObjects/$mergeObjects/$map/$arrayToObject/$filter删除空_a[]._p.s.k。T[]数组T和它们的键k.

  4. $map/$mergeObjects/$mergeObjects/$map/$arrayToObject/$filter删除空的_a[]._p。s:{}元素。

  5. $concat on _a和_a2将固定的_a[]数组元素与_a2[]中正确保存的元素连接起来。

  6. $取消临时数组_a2[],因为它已经在前一阶段与_a[]连接。

特别感谢@nimrod serok &@rickhg12hs为最初的想法!

游乐场

最新更新