hotdeal:
{ "property" : "ATL-D406" }
翻译:
{ "property" : "ATL-D406", "language" : "gb", "txt": [{"aaa":"hi", "bbb":"bye"}] }
{ "property" : "ATL-D406", "language" : "ru", "txt": [{"aaa":"priviet", "bbb":"baka"}] }
{ "property" : "ATL-D406", "language" : "cn", "txt": [{"aaa":"??", "bbb":"??"}] }
目前的结果:
{ "property":"ATL-D406", "language":[ "gb", "ru", "cn" ] }
我想要的是什么:
{ "property":"ATL-D406", "language":"gb", "aaa":"hi", "bbb":"bye" }
我无法理解为什么我的$ elemMatch不起作用,不应该将结果中的特定元素与#34;翻译"?
分开一旦我得到它只采取" gb"语言,我该如何投射" aaa"和" bbb"没有他们在阵列里面?我尝试了$ resolve,但后来我根本没有数据。你能解析数组中的数组吗? ($ resolve" txt")?
db.hotdeal.aggregate([
{ '$match': {} },
{ '$lookup': {
from: 'translation',
localField: 'property',
foreignField: 'property',
as: 'translations'
} },
{ '$match':
{ 'translations':
{ '$elemMatch': { 'language': 'gb' } }
}
},
{ '$project': {
_id: 0,
property: 1,
language: '$translations.language'
}}
])
答案 0 :(得分:1)
你做错了手术。您希望$filter
,$map
以及$arrayElemAt
看起来如此。 $elemMatch
运算符是"查询"操作"选择数据" ,并且不习惯于"过滤"数组内容。
db.hotdeal.aggregate([
{ '$match': {} },
{ '$lookup': {
'from': 'translation',
'localField': 'property',
'foreignField': 'property',
'as': 'translations'
} },
{ '$project': {
'_id': 0,
'property': 1,
'translation': {
'$arrrayElemAt': [
{ '$map': {
'input': {
'$filter': {
'input': '$translations'
'as': 't',
'cond': { '$eq': [ '$$t.language', 'gb' ] }
},
},
'as': 't',
'in': {
'language': '$$t',
'aaa': { '$arrayElemAt': [ '$$t.txt.aaa', 0 ] },
'bbb': { '$arrayElemAt': [ '$$t.txt.bbb', 0 ] }
}
}},
0
]
}
}},
{ '$project': {
'property': 1,
'language': '$translation.language',
'aaa': '$translation.aaa',
'bbb': '$translation.bbb'
}}
])
我通常会发现这些" trival" 结构更改最好在"客户端代码"而不是无论如何都要通过聚合框架。
所以简单地做"加入"然后让"客户"处理改动:
db.hotdeal.aggregate([
{ '$match': {} },
{ '$lookup': {
'from': 'translation',
'localField': 'property',
'foreignField': 'property',
'as': 'translations'
} }
]).forEach( doc => {
let translation = doc.translations.find( t => t.language === 'gb' );
doc.language = translation.language;
doc.aaa = translation.txt[0].aaa;
doc.bbb = translation.txt[0].bbb;
delete doc.translations;
delete doc._id;
printjson(doc);
});
所以这是做同样的事情,但远不那么迟钝。
答案 1 :(得分:0)
db.hotdeal.aggregate([
{ '$match': {} },
{ '$lookup': {
from: 'translation',
localField: 'property',
foreignField: 'property',
as: 'translations'
} },
{ '$unwind': '$translations' },
{ '$match': { 'translations.language': 'gb' } },
{ '$project': {
_id: 0,
property: 1,
language: '$translations.language',
aaa: '$translations.txt.aaa',
bbb: '$translations.txt.bbb'
}}
])