MongoDB 3次嵌套数组中的$pop元素
MongoDB $pop element which is in 3 time nested array
这是集合中每个文档的数据结构。数据结构是固定的。
{
'_id': 'some-timestamp',
'RESULT': [
{
'NUMERATION': [ // numeration of divisions
{
// numeration of producttypes
'DIVISIONX': [{'PRODUCTTYPE': 'product xy', COUNT: 100}]
}
]
}
]
}
查询结果应该是相同的结构,但只包含匹配 regular expression
.
的产品类型
我尝试使用嵌套的 $elemMatch
运算符,但这并没有让我更接近。 我不知道如何为每个部门迭代 producttypes 数组中的每个值。
我该怎么做? 然后我可以申请 $pop
、$in
和 $each
。
我看了:
- Querying an array of arrays in MongoDB
- https://docs.mongodb.com/manual/reference/operator/update/each/
- https://docs.mongodb.com/manual/reference/operator/update/pop/
...以及更多
我想避免的解决方案是这样写:
collection.find().forEach(function(x) { /* more for eaches */ })
编辑:
这是要复制的示例文档:
{"_id":"5ab550d7e85d5930b0879cbe","RESULT":[{"NUMERATION":[{"DIVISION":[{"PRODUCTTYPE":"Book","COUNT":10},{"PRODUCTTYPE":"Giftcard","COUNT":"300"}]}]}]}
例如查询结果应该只有 return 礼品卡条目:
{"_id":"5ab550d7e85d5930b0879cbe","RESULT":[{"NUMERATION":[{"DIVISION":[{"PRODUCTTYPE":"Giftcard","COUNT":"300"}]}]}]}
我希望您正在尝试 update
嵌套数组。
为此,您需要使用位置运算符 $[]
或 $
。
如果您使用 $[]
,您将能够删除所有匹配的嵌套数组元素。
如果您使用 $
,则只会删除第一个匹配的数组元素。
使用 $regex
运算符传递您的正则表达式。
另外,您需要使用$pull
根据匹配条件移除数组元素。在您的情况下,它是正则表达式。请注意 $elemMatch
不是与 $pull
一起使用的正确参数,因为 $pull
的参数是对数组的直接查询。
db.collection.update(
{/*additional matching conditions*/},
{$pull: {"RESULT.$[].NUMERATION.$[].DIVISIONX":{PRODUCTTYPE: {$regex: "xy"}}}},
{multi: true}
)
只需将xy
替换为您的正则表达式,并根据需要添加您自己的匹配条件即可。我不太确定你的数据集,但我根据给定信息的假设得出了上述答案。随意根据您的要求进行更改。
使用 forEach
方法结果格式正确。我仍在寻找不涉及使用该功能的更好方法 - 因此 我不会将其标记为答案。
但目前这一切正常:
db.collection.find().forEach(
function(wholeDocument) {
wholeDocument['RESULT'].forEach(function (resultEntry) {
resultEntry['NUMERATION'].forEach(function (numerationEntry) {
numerationEntry['DIVISION'].forEach(function(divisionEntry, index) {
// example condition (will be replaced by regular expression evaluation)
if(divisionEntry['PRODUCTTYPE'] != 'Giftcard'){
numerationEntry['DIVISION'].splice(index, 1);
}
})
})
})
print(wholeDocument);
}
)
更新
感谢 Rahul Raj 的评论,我已经阅读了使用 $redact
运算符的聚合。这个问题的解决方案的原型是这个查询:
db.getCollection('DeepStructure').aggregate( [
{ $redact: {
$cond: {
if: { $ne: [ "$PRODUCTTYPE", "Giftcard" ] },
then: "$$DESCEND",
else: "$$PRUNE"
}
}
}
]
)
这是集合中每个文档的数据结构。数据结构是固定的。
{
'_id': 'some-timestamp',
'RESULT': [
{
'NUMERATION': [ // numeration of divisions
{
// numeration of producttypes
'DIVISIONX': [{'PRODUCTTYPE': 'product xy', COUNT: 100}]
}
]
}
]
}
查询结果应该是相同的结构,但只包含匹配 regular expression
.
我尝试使用嵌套的 $elemMatch
运算符,但这并没有让我更接近。 我不知道如何为每个部门迭代 producttypes 数组中的每个值。
我该怎么做? 然后我可以申请 $pop
、$in
和 $each
。
我看了:
- Querying an array of arrays in MongoDB
- https://docs.mongodb.com/manual/reference/operator/update/each/
- https://docs.mongodb.com/manual/reference/operator/update/pop/
...以及更多
我想避免的解决方案是这样写:
collection.find().forEach(function(x) { /* more for eaches */ })
编辑: 这是要复制的示例文档:
{"_id":"5ab550d7e85d5930b0879cbe","RESULT":[{"NUMERATION":[{"DIVISION":[{"PRODUCTTYPE":"Book","COUNT":10},{"PRODUCTTYPE":"Giftcard","COUNT":"300"}]}]}]}
例如查询结果应该只有 return 礼品卡条目:
{"_id":"5ab550d7e85d5930b0879cbe","RESULT":[{"NUMERATION":[{"DIVISION":[{"PRODUCTTYPE":"Giftcard","COUNT":"300"}]}]}]}
我希望您正在尝试 update
嵌套数组。
为此,您需要使用位置运算符 $[]
或 $
。
如果您使用 $[]
,您将能够删除所有匹配的嵌套数组元素。
如果您使用 $
,则只会删除第一个匹配的数组元素。
使用 $regex
运算符传递您的正则表达式。
另外,您需要使用$pull
根据匹配条件移除数组元素。在您的情况下,它是正则表达式。请注意 $elemMatch
不是与 $pull
一起使用的正确参数,因为 $pull
的参数是对数组的直接查询。
db.collection.update(
{/*additional matching conditions*/},
{$pull: {"RESULT.$[].NUMERATION.$[].DIVISIONX":{PRODUCTTYPE: {$regex: "xy"}}}},
{multi: true}
)
只需将xy
替换为您的正则表达式,并根据需要添加您自己的匹配条件即可。我不太确定你的数据集,但我根据给定信息的假设得出了上述答案。随意根据您的要求进行更改。
使用 forEach
方法结果格式正确。我仍在寻找不涉及使用该功能的更好方法 - 因此 我不会将其标记为答案。
但目前这一切正常:
db.collection.find().forEach(
function(wholeDocument) {
wholeDocument['RESULT'].forEach(function (resultEntry) {
resultEntry['NUMERATION'].forEach(function (numerationEntry) {
numerationEntry['DIVISION'].forEach(function(divisionEntry, index) {
// example condition (will be replaced by regular expression evaluation)
if(divisionEntry['PRODUCTTYPE'] != 'Giftcard'){
numerationEntry['DIVISION'].splice(index, 1);
}
})
})
})
print(wholeDocument);
}
)
更新
感谢 Rahul Raj 的评论,我已经阅读了使用 $redact
运算符的聚合。这个问题的解决方案的原型是这个查询:
db.getCollection('DeepStructure').aggregate( [
{ $redact: {
$cond: {
if: { $ne: [ "$PRODUCTTYPE", "Giftcard" ] },
then: "$$DESCEND",
else: "$$PRUNE"
}
}
}
]
)