在mongodb查询后过滤数组中返回的元素

时间:2015-04-23 12:06:49

标签: java mongodb mongodb-query mongodb-java

如果我理解正确,这在mongodb中被称为projection。我已经看到有两种类型的有用投影运算符:elemMatch$

我有一组文档,每个文档都有一个属性列表(Object)。我想执行复杂的查询来匹配这些属性,即匹配其中的几个字段(使用regex等)。

现在,当文档与查询匹配时,Java驱动程序将返回整个文档。我想过滤它以返回与原始查询匹配的属性。

我尝试过组合elemMatch,但我所能完成的只是返回所有属性或只返回一个(通常是第一个匹配)。

Mongo文档结构如下:

    {
    "name": "MediaPlayer",
    "attributes": [
        {
            "tag": "media",
            "values": [
                "mp3",
                "mp4"
            ]
        },
        {
            "tag": "teste",
            "values": [
                "teste"
            ]
        }
    ]
}

我的查询为:

{attributes : {$elemMatch: { 'tag' : 'media'},$elemMatch: { 'tag' : 'stream'}}}

并返回以下结果:

{
    "name": "MediaStream",
    "attributes": [
        {
            "tag": "media",
            "values": [
                "Edit"
            ]
        },
        {
            "tag": "stream",
            "values": [
                "Edit"
            ]
        },
        {
            "tag": "video",
            "values": [
                "Edit"
            ]
        }
    ]
}

示例和返回的是不同的文档。虽然我匹配two属性,但我返回了整个列表。

我希望attributes数组只包含匹配的元素。

我怎么能这样做?

编辑:

从我所看到的mongodb find操作不支持内部数组过滤。有一些使用mongodb聚合框架的例子。除此之外,手动过滤似乎是唯一可行的方法。

2 个答案:

答案 0 :(得分:1)

找到了一个可能的解决方案:Solution A

编辑:找到的聚合证明不能提供问题的一般解决方案,因为我不控制查询。从这个意义上说,如果我想要展开属性然后将它与查询匹配,它将只适用于匹配单个属性的查询。

答案 1 :(得分:1)

我们假设您要匹配tag:mediatag:stream,这种情况下您在mongo $in汇总查询中输入了匹配条件,如下所示

db.collectionName.aggregate({
"$unwind": "$attributes" // first unwind attributes array 
}, {
"$match": {
  "attributes.tag": {
    "$in": ["media", "stream"] // put all matching tags in array using $in
  }
}
}, {
"$group": {
  "_id": "$_id",
  "name": {
    "$first": "$name"
  },
  "attributes": {
    "$push": "$attributes" // push all attributes to get only matching tags
  }
}
}).pretty()