【问题标题】:Getting a distinct aggregation of an array field across indexes跨索引获取数组字段的不同聚合
【发布时间】:2012-08-24 09:19:32
【问题描述】:

我正在尝试学习 MongoDB 以及它对我的分析有何用处。我只是在玩他们网站上提供的 JavaScript 控制台,并创建了以下项目:

{"title": "Cool", "_id": {"$oid": "503e4dc0cc93742e0d0ccad3"}, "tags": ["twenty", "sixty"]}
{"title": "Other", "_id": {"$oid": "503e4e5bcc93742e0d0ccad4"}, "tags": ["ten", "thirty"]}
{"title": "Ouch", "_id": {"$oid": "503e4e72cc93742e0d0ccad5"}, "tags": ["twenty", "seventy"]}
{"title": "Final", "_id": {"$oid": "503e4e72cc93742e0d0ccad6"}, "tags": ["sixty", "seventy"]}

我想做的是查询,所以我得到了所有这些对象的唯一标签列表。结果应如下所示:

["ten", "twenty", "thirty", "sixty", "seventy"]

我该如何查询?我正在尝试 distinct() 它,但调用总是失败,甚至没有查询。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    他们网站上失败的代码在实际的 MongoDB 实例上运行:

    > db.posts.insert({title: "Hello", tags: ["one", "five"]});
    > db.posts.insert({title: "World", tags: ["one", "three"]});
    > db.posts.distinct("tags");
    [ "one", "three", "five"]
    

    很奇怪。

    【讨论】:

    • 您收到什么错误信息?我相信控制台运行在一个非常旧的 mongo 版本上......
    【解决方案2】:

    有几个 web mongo 控制台可用:

    但如果你在其中输入帮助,你会发现它们只支持极少数的操作:

    HELP
    Note: Only a subset of MongoDB's features are provided here.
    For everything else, download and install at mongodb.org.
    
    db.foo.help()                 help on collection method
    db.foo.find()                 list objects in collection foo
    db.foo.save({a: 1})           save a document to collection foo
    db.foo.update({a: 1}, {a: 2}) update document where a == 1
    db.foo.find({a: 1})           list objects in foo where a == 1
    
    it                            use to further iterate over a cursor
    

    由于不受支持,因此这种 distinct 不起作用。

    【讨论】:

    • @wkhatch 如果您再次阅读该问题,OP 会询问如何在 MongoDB 网站上提供的 Web 控制台中进行聚合。我正确回答你不能
    【解决方案3】:

    您可以使用聚合框架。根据您希望结果结构的方式,您可以使用任一

    var pipeline = [ 
            {"$unwind": "$tags" } ,
            { "$group": { _id: "$tags" } }
        ];
    R = db.tb.aggregate( pipeline );
    printjson(R);
    
    {
            "result" : [
                    {
                            "_id" : "seventy"
                    },
                    {
                            "_id" : "ten"
                    },
                    {
                            "_id" : "sixty"
                    },
                    {
                            "_id" : "thirty"
                    },
                    {
                            "_id" : "twenty"
                    }
            ],
            "ok" : 1
    }
    

    var pipeline = [ 
            {"$unwind": "$tags" } ,
            { "$group": 
                { _id: null, tags: {"$addToSet": "$tags" }  }
            }
        ];
    R = db.tb.aggregate( pipeline );
    printjson(R);
    
    {
            "result" : [
                    {
                            "_id" : null,
                            "tags" : [
                                    "seventy",
                                    "ten",
                                    "sixty",
                                    "thirty",
                                    "twenty"
                            ]
                    }
            ],
            "ok" : 1
    }
    

    【讨论】:

    • 谢谢。这真的很有帮助。如果我们想将标签写入另一个集合怎么办?
    【解决方案4】:

    你应该可以使用这个:

    db.mycollection.distinct("tags").sort()
    

    【讨论】:

      【解决方案5】:

      另一种使用聚合管道获取唯一数组元素的方法

      db.blogs.aggregate(
        [
          {$group:{_id : null, uniqueTags : {$push : "$tags"}}},
          {$project:{
            _id : 0,
            uniqueTags : {
              $reduce : {
                input : "$uniqueTags", 
                initialValue :[], 
                in : {$let : {
                  vars : {elem : { $concatArrays : ["$$this", "$$value"] }},
                  in : {$setUnion : "$$elem"}
                }}
              }
            }
          }}
        ]
      )
      

      收藏

      > db.blogs.find()
      { "_id" : ObjectId("5a6d53faca11d88f428a2999"), "name" : "sdfdef", "tags" : [ "abc", "def", "efg", "abc" ] }
      { "_id" : ObjectId("5a6d5434ca11d88f428a299a"), "name" : "abcdef", "tags" : [ "abc", "ijk", "lmo", "zyx" ] }
      > 
      

      管道

      >   db.blogs.aggregate(
      ...     [
      ...       {$group:{_id : null, uniqueTags : {$push : "$tags"}}},
      ...       {$project:{
      ...         _id : 0,
      ...         uniqueTags : {
      ...           $reduce : {
      ...             input : "$uniqueTags", 
      ...             initialValue :[], 
      ...             in : {$let : {
      ...               vars : {elem : { $concatArrays : ["$$this", "$$value"] }},
      ...               in : {$setUnion : "$$elem"}
      ...             }}
      ...           }
      ...         }
      ...       }}
      ...     ]
      ...   )
      

      结果

      { "uniqueTags" : [ "abc", "def", "efg", "ijk", "lmo", "zyx" ] }
      

      【讨论】:

      猜你喜欢
      • 2015-11-14
      • 2022-12-09
      • 2015-12-20
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      • 2015-11-05
      • 2019-04-13
      相关资源
      最近更新 更多