我的收藏集中有以下物品:
{
"_id" : ObjectId("5c0325eec104041f38a6f9ec"),
"total_distict_words" : 137,
"items" : [
{
"first" : 1
},
{
"another" : 3
},
{
"house" : 5
},
.....
我正在尝试对出现在items数组中的热门单词进行排序和过滤。
问题在于“项目”具有下一个模板:{ <word>: <value> }
我试图进行操作或改造,但没有成功。
首先,如何使用mongodb和聚合对“ stats.items”数组进行操作?
第二,如何以字典形式转换,例如:
{ "llegaron": 1 } => { word: "llegaron", counter: "1" }
问题是,当我使用某些元素进行操作时,我必须知道要访问的字段的名称,例如:
# users: [<name, age, posts>]
db.users.aggregate([{ $sort : { age : -1, posts: 1 }}] )
答案 0 :(得分:0)
我敢肯定,您可以通过一种更短的途径来实现这一目标,但是这里有些事情要玩:
db.collection.aggregate([
{ $unwind: "$items" },
{ $project: { items: { $objectToArray: "$items" } } },
{ $project: {
items: {
$map: {
input: "$items",
as: "item",
in: {
word: "$$item.k",
counter: "$$item.v"
}
}
}
}
},
{ "$group": { "_id": "$_id", "items": { "$push": "$items" } } },
{ "$project": {
"items": {
"$reduce": {
"input": "$items",
"initialValue": [],
"in": {
"$setUnion": [
"$$value",
"$$this"
]
}
}
}
}
},
{ $unwind: "$items" },
{ $sort: { "items.counter": -1 }},
{ "$group": { "_id": "$_id", "items": { "$push": "$items" } } }
])
这个想法是先使用$objectToArray
,然后使用$map
将k:v
转换为word: k, value: v
,然后剩下的只是一种将数组项通过几项排序的方法项目/组和$sort
。
我们还使用$reduce
和$setUnion
对由{ "$group": { "_id": "$_id", "items": { "$push": "$items" } } },
结束的讨厌的数组进行分组。
在一天结束时,请使用波纹管,并遵循管道的每个步骤,以真正了解其含义和目的。我敢肯定有一种更短的方法来获得相同的结果,等等...
您还可以将{ $sort: { "items.counter": -1 }},
的{{1}}行中的排序顺序更改为asc
的{{1}}
您可以看到它working here