2015-04-23 248 views
0

如果我理解正确,这在mongodb中称为projection。我已经看到有两种有用的预测算子:elemMatch$在mongodb查询后过滤返回的数组中的元素

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

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

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

蒙戈文档结构如下:

{ 
    "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属性,但我得到了返回的整个列表。

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

我该如何做到这一点?

编辑:

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

+0

你能告诉我们一些样本文档这种情况下,你已经尝试和预期结果的代码? – chridam

+0

@chridam完成。如果需要其他东西,请说。 –

+1

@Saraiva'$ elemMatch'有限制,只返回匹配'$ elemMatch'条件的第一个元素,如果你运行这个查询'{“attributes”:{“$ elemMatch”:{“tag”:“media”} },“attributes”:{“$ elemMatch”:{“tag”:“teste”}}},{“attributes。$。tag”:1}'只返回一个匹配数组而不是整个数组,所以如果你想找出所有匹配的数组,然后应该使用mongo聚合 – Yogesh

回答

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() 
+0

非常感谢您的帮助。我意识到我必须限制查询输入并做类似的事情。后期更新与完整的解决方案和描述。 –

1

发现了一个可能的解决方案:Solution A

编辑:聚集发现并不能证明,提供解决问题的一般解决方案,因为我没有控制查询。从这个意义上讲,如果我想展开属性,然后将其与查询进行匹配,那么它将只适用于匹配单个属性的查询。

+1

根据我的理解,我认为你想匹配两个标签,像'tag:media'和'tag:stream'一样放松吗?你不能写聚合查询吗? – Yogesh

+0

@yogesh从一个未知的查询(不是由我创建的)我想,如果一个文档匹配,知道哪些注册的属性给了一个积极的匹配。例如,如果我有一个具有10个属性和查询匹配7的文档。我希望查询返回完整的文档,只有7个匹配的属性。因此,这是一个过滤数组的情况。 –