来自子文档的Mongo聚合/投影

时间:2013-08-19 15:41:45

标签: javascript mongodb

无法理解查询此mongo文档的具体语法。 我想得到(项目?)只有“条目”,其中u =“123”。 我尝试过类似的东西:

db["conv_msgs_822"].aggregate({$match: {"_id": "1234", "entries.$.u" : "123"}})

哪个失败了。这甚至可能吗?

{
  "_id" : "1234",
  "entries" : {
    "1" : {
      "body" : "aesf asdf asdf asdf asdf",
      "u" : "123"
    },
    "2" : {
      "body" : "1234",
      "u" : ""
    },
    "3" : {
      "body" : "some other body ",
      "u" : "14"
    },
    "4" : {
      "body" : "another body",
      "u" : "123"
    }
  }
}

2 个答案:

答案 0 :(得分:3)

目前的文档结构无法实现这一点。你真的需要这些子文档在一个数组中做这样的事情。

假设您重新构建了与此匹配的文档(如果需要在子文档中,您甚至可以将索引添加回字段):

{
  "_id" : "1234",
  "entries" : [
    {
      "body" : "aesf asdf asdf asdf asdf",
      "u" : "123"
    },
    {
      "body" : "1234",
      "u" : ""
    },
    {
      "body" : "some other body ",
      "u" : "14"
    },
    {
      "body" : "another body",
      "u" : "123"
    }
  ]
}

然后,您可以使用基本查询与$运算符作为投影,以仅匹配第一项。

> db.conv_msgs_822.find({"_id": "1234", "entries.u": "123"}, {"entries.$": 1})

哪会产生:

{ "_id" : "1234", "entries" : [ { "body" : "aesf asdf asdf asdf asdf", "u" : "123" } ] }

要匹配您需要聚合的所有项目,并$unwind他们$match子元素和$group他们回来。

db.conv_msgs_822.aggregate(
  {$match: {"_id": "1234", "entries.u": "123"}},
  {$unwind: "$entries"},
  {$match: {"entries.u": "123"}},
  {$group: {_id: "$_id", entries: {$push: "$entries"}}}
)

导致:

{
    "result" : [
        {
            "_id" : "1234",
            "entries" : [
                {
                    "body" : "aesf asdf asdf asdf asdf",
                    "u" : "123"
                },
                {
                    "body" : "another body",
                    "u" : "123"
                }
            ]
        }
    ],
    "ok" : 1
}

我希望有所帮助。

答案 1 :(得分:0)

到目前为止,对我来说最好的潜力是:

db.eval( function(doc, u_val) {
            var msgs = doc["entries"];
            var cleaned_entries = {};
              for (var k in entries){
                if (msgs[k].u == u_val){
                  cleaned_entries[k] = entries[k];
                  }
              };
            doc["entries"] = cleaned_entries

            return doc
         },
         db["conv_msgs_822"].findOne({"_id": "1234"}), 123 );
相关问题