我有一个奇怪的数据库结构如下:
我有一个具有普通属性的文档,然后我有一个元数据属性,它是一个对象数组。
metadata: {[
{
key: [key],
value: [value]
},
...
]}
修改:永远不会有具有重复键的元数据子文档
这样做是为了保留元数据对象的顺序
现在我想获得具有给定键的元数据对象的不同值。
我希望使用MongoDB找到[key] =“x”的每个不同的[value]。并且在数组(而不是文档)中返回不同的值
我想使用distinct命令是不可能的,但这可能是使用聚合管道还是我必须使用Map-Reduce?
有什么建议吗?
提前致谢! :)
答案 0 :(得分:3)
我认为你的意思是:
{
"metadata": [
{ "key": "abc", "value": "borf" },
{ "key": "cdc", "value": "biff" }
]
},
{
"metadata": [
{ "key": "bbc", "value": "barf" },
{ "key": "abc", "value": "borf" },
{ "key": "abc", "value": "barf" }
]
}
如果您过滤“abc”并获得不同的“值”条目,请执行以下操作:
db.collection.aggregate([
{ "$match": { "metadata.key": "abc" } },
{ "$unwind": "$metadata" },
{ "$match": { "metadata.key": "abc" } },
{ "$group": {
"_id": "$metadata.value"
}}
])
甚至更好:
db.collection.aggregate([
{ "$match": { "metadata.key": "abc" } },
{ "$redact": {
"$cond": {
"if": { "$eq": [ { "$ifNull": [ "$key", "abc" ] }, "abc" ] },
"then": "$$DESCEND",
"else": "$$PRUNE"
}
}},
{ "$unwind": "$metadata" },
{ "$group": {
"_id": "$metadata.value",
"count": { "$sum": 1 }
}}
])
基本上会给出:
{ "_id": "barf", "count": 1 },
{ "_id": "borf", "count": 2 }
但是不可能这只是一个“barf”和“borf”的数组。 distinct()
方法仅执行一系列键,但它也非常有限。因此它只能这样做:
db.collection.distinct("metadata.value",{ "metadata.key": "abc" })
[ "biff", "borf", "barf" ]
结果不正确。因此,只需从上面获取“文档”结果并应用一些“后期处理”:
db.collection.aggregate([
{ "$match": { "metadata.key": "abc" } },
{ "$redact": {
"$cond": {
"if": { "$eq": [ { "$ifNull": [ "$key", "abc" ] }, "abc" ] },
"then": "$$DESCEND",
"else": "$$PRUNE"
}
}},
{ "$unwind": "$metadata" },
{ "$group": {
"_id": "$metadata.value"
}}
]).map(function(doc) {
return doc._id;
})
结果是一个只有不同值的简单数组:
[ "borf", "barf" ]