查询嵌套数组

时间:2013-08-13 04:59:27

标签: mongodb mongoose

我有一个用户集合,其架构如下:

var userSchema = new mongoose.Schema({
  id : Number,
  tags                  : 
    [
      {
        tag_name : String,
        tag_url  : String, 
        posts    : 
          [
            {
                post_id: String
            }
          ]
      }                  
    ]
});

我想要做的只是检索其post_id值在posts数组中的tag_name。 所以,我尝试了如下查询

db.users.find({'tags.posts.post_id':'000000'}, {'tags.tag_name':1})

不幸的是,虽然post_id不在posts数组中,但我得到了所有tag_name。

你能帮我写这个查询吗?

编辑============================================== ===================

我们说我的数据如下:

tags
[
  { 
    tag_name: 'java',
    posts   : [{post_id:'000000'}, {post_id:'111111'}
  },
  { 
    tag_name: 'ruby',
    posts   : [{post_id:'000000'}, {post_id:'111111'}
  },
  { 
    tag_name: 'php',
    posts   : [{post_id:'111111'}
  },
]

我希望post_id有标签元素,如果我通过post_id搜索是&00; 000000'我想只获取tag_name为' java'的标签元素。和' ruby​​'不是最后一个标签元素,是否可能?

1 个答案:

答案 0 :(得分:1)

$中的{p> tags.$.tag_name应该有所帮助:

db.users.find({'tags.posts.post_id':'000000'}, {'tags.$.tag_name':1})

修改 好的,我看了你的更新。在这种情况下,我在聚合框架中看到了一个解决方案。我们可以尝试构建这样的管道:

db.col.aggregate(
    {$match: {'tags.posts.post_id':'000000'}}, 
    {$unwind: '$tags'}, 
    {$match: {'tags.posts.post_id':'000000'}}, 
    {$group: {_id:'$_id', tags: {$push: '$tags'}}}
)

结果将是:

{
        "_id" : ObjectId("5209f5e4ef21a864f6f6ed54"),
        "tags" : [
            {
                "tag_name" : "java",
                "posts" : [
                    { "post_id" : "000000" },
                    { "post_id" : "111111" }
                ]
            },
            {
                "tag_name" : "ruby",
                "posts" : [
                    { "post_id" : "000000" },
                    { "post_id" : "111111" }
                ]
            }
        ]
}

您可能会看到我$match两次。这是出于性能目的。通过首先匹配,我们从集合中减少包含post_id:000000的文档集。第二次匹配过滤器tags