Mongo 根据多个字段(包括嵌套)的映射追加到标准化字符串字段
Mongo append to standardized string field based on mapping of multiple fields (including nested)
我有一个大型集合,其中包含以下字段:
{
'class': 'apple'
},
{
'class': 'appl'
},
{
'class': 'orange',
'nested': [
{'classification': 'app'},
{'classification': 'A',
{'classification': 'orang'}
]
},
{
'nested': [
{'classification': 'O'},
{'classification': 'unknown'}
]
}
我还有一个 Python 字典映射字段值,如:
{
'class': {
'apple': 'a',
'appl': 'a',
'orange': 'o'
},
'nested.classification': {
'app': 'a',
'A': 'a',
'orang': 'o',
'O': 'o',
'unknown': 'u'
}
}
我正在尝试(在 PyMongo 中)更新我的 MongoDB 集合,以便从顶级 class
字段和嵌套 nested.classification
个字段。
在上面,这将产生以下更新:
{
'class': 'apple'
'standard': 'a'
},
{
'class': 'appl'
'standard': 'a'
},
{
'class': 'orange',
'nested': [
{'classification': 'app'},
{'classification': 'A',
{'classification': 'orang'}
]
'standard': 'oaao'
},
{
'nested': [
{'classification': 'O'},
{'classification': 'unknown'}
]
'standard': 'ou'
}
我怎样才能大规模有效地做到这一点?在聚合框架内?
只需 3 个步骤,您就可以得到想要的结果
注意: MongoDB只能迭代数组,所以我们需要把你的字典转成{k:"key", v: "value"}
数组(我们可以用$objectToArray , 但不值得)
- 我们通过迭代 Python
class
字典映射 class
字段
- 我们通过迭代 Python
nested.classification
字典 nested classification
映射值
- 我们将映射值连接成一个值
- (可选)如果需要持久化,运行
$merge
阶段
免责声明: MongoDB >=4.2 + 我不确定这个解决方案是否适用
db.collection.aggregate([
{
"$addFields": {
standard: {
$reduce: {
input: [
{ k: "apple", v: "a" },
{ k: "appl", v: "a" },
{ k: "orange", v: "o" }
],
initialValue: "",
in: {
$cond: [
{
$eq: ["$$this.k", "$class"]
},
"$$this.v",
"$$value"
]
}
}
}
}
},
{
"$addFields": {
standard: {
$reduce: {
input: {
"$ifNull": [ "$nested", [] ]
},
initialValue: [ { v: "$standard" } ],
in: {
$concatArrays: [
"$$value",
{
$filter: {
input: [
{ k: "app", v: "a" },
{ k: "A", v: "a" },
{ k: "orang", v: "o" },
{ k: "O", v: "o" },
{ k: "unknown", v: "u" }
],
as: "nested",
cond: {
$eq: [ "$$this.classification", "$$nested.k" ]
}
}
}
]
}
}
}
}
},
{
"$addFields": {
"standard": {
$reduce: {
input: "$standard.v",
initialValue: "",
in: {
"$concat": [ "$$value", "$$this" ]
}
}
}
}
},
//Optional - If you need to persist it
{
$merge: {
into: "collection",
on: "_id",
whenMatched: "replace"
}
}
])
我有一个大型集合,其中包含以下字段:
{
'class': 'apple'
},
{
'class': 'appl'
},
{
'class': 'orange',
'nested': [
{'classification': 'app'},
{'classification': 'A',
{'classification': 'orang'}
]
},
{
'nested': [
{'classification': 'O'},
{'classification': 'unknown'}
]
}
我还有一个 Python 字典映射字段值,如:
{
'class': {
'apple': 'a',
'appl': 'a',
'orange': 'o'
},
'nested.classification': {
'app': 'a',
'A': 'a',
'orang': 'o',
'O': 'o',
'unknown': 'u'
}
}
我正在尝试(在 PyMongo 中)更新我的 MongoDB 集合,以便从顶级 class
字段和嵌套 nested.classification
个字段。
在上面,这将产生以下更新:
{
'class': 'apple'
'standard': 'a'
},
{
'class': 'appl'
'standard': 'a'
},
{
'class': 'orange',
'nested': [
{'classification': 'app'},
{'classification': 'A',
{'classification': 'orang'}
]
'standard': 'oaao'
},
{
'nested': [
{'classification': 'O'},
{'classification': 'unknown'}
]
'standard': 'ou'
}
我怎样才能大规模有效地做到这一点?在聚合框架内?
只需 3 个步骤,您就可以得到想要的结果
注意: MongoDB只能迭代数组,所以我们需要把你的字典转成{k:"key", v: "value"}
数组(我们可以用$objectToArray , 但不值得)
- 我们通过迭代 Python
class
字典映射class
字段 - 我们通过迭代 Python
nested.classification
字典nested classification
映射值 - 我们将映射值连接成一个值
- (可选)如果需要持久化,运行
$merge
阶段
免责声明: MongoDB >=4.2 + 我不确定这个解决方案是否适用
db.collection.aggregate([
{
"$addFields": {
standard: {
$reduce: {
input: [
{ k: "apple", v: "a" },
{ k: "appl", v: "a" },
{ k: "orange", v: "o" }
],
initialValue: "",
in: {
$cond: [
{
$eq: ["$$this.k", "$class"]
},
"$$this.v",
"$$value"
]
}
}
}
}
},
{
"$addFields": {
standard: {
$reduce: {
input: {
"$ifNull": [ "$nested", [] ]
},
initialValue: [ { v: "$standard" } ],
in: {
$concatArrays: [
"$$value",
{
$filter: {
input: [
{ k: "app", v: "a" },
{ k: "A", v: "a" },
{ k: "orang", v: "o" },
{ k: "O", v: "o" },
{ k: "unknown", v: "u" }
],
as: "nested",
cond: {
$eq: [ "$$this.classification", "$$nested.k" ]
}
}
}
]
}
}
}
}
},
{
"$addFields": {
"standard": {
$reduce: {
input: "$standard.v",
initialValue: "",
in: {
"$concat": [ "$$value", "$$this" ]
}
}
}
}
},
//Optional - If you need to persist it
{
$merge: {
into: "collection",
on: "_id",
whenMatched: "replace"
}
}
])