我有MongoDb的优惠收藏。
[
{
"Name": "item01",
"Descriptions": [
{
"Name": "(es) Item01 Name",
"Culture": "es"
},
{
"Name": "(en) Item01 Name",
"Culture": "en"
},
{
"Name": "(de) Item01 Name",
"Culture": "de"
}
]
},
{
"Name": "item02",
"Descriptions": [
{
"Name": "(en) Item02 Name",
"Culture": "en"
},
{
"Name": "(de) Item03 Name",
"Culture": "de"
}
]
}
]
我需要按说明对项目列表进行排序。
必须由用户文化订购。如果没有这样的文化,必须默认使用英语。
我试图使用mongo聚合来解决这个问题。但无法找到。
db.Offer.aggregate(
[
{$unwind:'$Descriptions'},
{$group: {
'_id': '$_id',
'Culture': '$Culture',
'ElementNameComp': {$first: {$cond:[
{$eq:['$Descriptions.Culture', 'es']},
'$Descriptions.Name',
{$cond:[
{$eq:['$Descriptions.Culture', 'en']},
'$Descriptions.Name',
'no exists EN'
]}
]} }
}}
]
)
一些想法?
更新
文化时的预期结果(ES)。我还修改了数据以涵盖更多示例。
[
{
"Name": "item01",
"Descriptions": "(es) Item01 Name"
},
{
"Name": "item02",
"Descriptions": "(en) Item02 Name"
}
]
答案 0 :(得分:1)
你需要一些东西来分配一个"得分"为了确定哪个是最好的,可以匹配可能的匹配作为基本过程。
一种可以过滤"的方法。 $unwind
之前的数组内容:
var locale = "es";
var result = db.Offer.aggregate([
{ "$project": {
"Name": 1,
"Descriptions": {
"$setDifference": [
{ "$map": {
"input": "$Descriptions",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.Culture", locale ] },
{ "name": "$$el.Name", "score": { "$literal": 2 } },
{ "$cond": [
{ "$eq": [ "$$el.Culture", "en" ] },
{ "name": "$$el.Name", "score": { "$literal": 1 } },
false
]}
]
}
}},
[false]
]
}
}},
{ "$unwind": "$Descriptions" },
{ "$sort": { "Descriptions.score": -1 }},
{ "$group": {
"_id": "$_id",
"Name": { "$first": "$Name" },
"Description": { "$first": "$Descriptions.name" }
}}
]);
这剥夺了"描述"的一些结构。但它基本上似乎是你想要的。原因是只采用所选语言环境的值或以其他方式回退到"默认"如果没有其他项目匹配,则为英语语言环境。
$cond
运算符分配"得分"匹配的值,然后相应地对它们进行排序,以便"最高"得分返回。
然后你排序并分组回你的数组。
你可以在MongoDB 2.6之前做同样的事情,它给出了额外的运算符:
var locale = "es";
var result = db.Offer.aggregate([
{ "$unwind": "$Descriptions" },
{ "$project": {
"Name": 1,
"Descriptions": {
"$cond": [
{ "$eq": [ "$Descriptions.Culture", locale ] },
{ "name": "$Descriptions.Name", "score": { "$const": 2 } },
{ "$cond": [
{ "$eq": [ "$Descriptions.Culture", "en" ] },
{ "name": "$Descriptions.Name", "score": { "$const": 1 } },
false
]}
]
}
}},
{ "$match": { "Descriptions": { "$ne": false } }},
{ "$sort": { "Descriptions.score": -1 } },
{ "$group": {
"_id": "$_id",
"Name": { "$first": "$Name" },
"Description": { "$first": "$Descriptions.name" }
}}
]);
在任何一种情况下,当匹配语言环境时,结果应为:
{
"_id" : ObjectId("539f91f831d29097dc43e8ae"),
"Name" : "item02",
"Description" : "(es) Item02 Name"
},
{
"_id" : ObjectId("539f91f831d29097dc43e8ad"),
"Name" : "item01",
"Description" : "(es) Item01 Name"
}
或者在设置不存在的区域设置时
{
"_id" : ObjectId("539f91f831d29097dc43e8ae"),
"Name" : "item02",
"Description" : "(en) Item02 Name"
},
{
"_id" : ObjectId("539f91f831d29097dc43e8ad"),
"Name" : "item01",
"Description" : "(en) Item01 Name"
}
任何甚至没有违约的结果" en"语言环境将被省略。