如何使用mongodb中的项目数组进行操作(过滤和排序)?

时间:2018-12-09 19:32:48

标签: arrays mongodb aggregation-framework

我的收藏集中有以下物品:

{
    "_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 }}] )

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,然后使用$mapk:v转换为word: k, value: v,然后剩下的只是一种将数组项通过几项排序的方法项目/组和$sort

我们还使用$reduce$setUnion对由{ "$group": { "_id": "$_id", "items": { "$push": "$items" } } },结束的讨厌的数组进行分组。

在一天结束时,请使用波纹管,并遵循管道的每个步骤,以真正了解其含义和目的。我敢肯定有一种更短的方法来获得相同的结果,等等...

您还可以将{ $sort: { "items.counter": -1 }},的{​​{1}}行中的排序顺序更改为asc的{​​{1}}

您可以看到它working here