2016-04-07 90 views
0

任何人都可以告诉我如何将$ match阶段添加到聚合管道以过滤字段匹配查询的位置(并且可能有其他数据也在其中),而不是将结果限制到字段等于查询的条目?

查询规范...

var query = {hello:"world"}; 

...可以用来检索使用MongoDB的本地节点的驱动程序,在查询“地图”被解释为一个的查找()操作下列文件比赛...

{hello:"world"} 
{hello:"world", extra:"data"} 

...喜欢...

collection.find(query); 

同样的查询图也可以interprete d与$ elemMatch用于检索与包含在象上述文件阵列匹配的条目的文件时的匹配...

​​

...使用如[PIPELINE1]调用...

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
]).toArray() 

然而,试图获得匹配的问候与开卷[PIPELINE2]列表...

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
    {$unwind:"$greetings"}, 
]).toArray() 

...产生任何匹配项的文件里面的所有数组条目,包括条目w^HICH不匹配(简化的结果)...

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world", extra:"data"}}, 
    {greetings:{hello:"world"}}, 
    {greetings:{aloha:"mars"}}, 
] 

我一直在试图添加第二个比赛阶段,但我很惊讶地发现,它的结果仅限于那些问候字段等于查询,而不是匹配查询[PIPELINE3]的位置。

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
    {$unwind:"$greetings"}, 
    {$match:{greetings:query}}, 
]).toArray() 

不幸的是PIPELINE3只产生以下条目,排除匹配的Hello World入门与额外的“数据”,因为该条目不严格“平等”的查询(简化的结果)...

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world"}}, 
] 

...这里是我需要的结果是相当...

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world"}}, 
    {greetings:{"hello":"world","extra":"data"} 
] 

我如何可以添加第二个$匹配阶段PIPELIN E2,筛选问候字段匹配查询的位置(也可能包含其他数据),而不是将结果限制为问候字段等于查询的条目?

回答

0

你在结果中看到的是正确的。你的方法有点不对。如果你想你期待的结果,那么你应该使用这种方法:每当你在MongoDB中使用aggregation

[ 
    {greetings:{hello:"world"}}, 
    {greetings:{hello:"world"}}, 
    {greetings:{"hello":"world","extra":"data"} 
] 

和:

collection.aggregate([ 
    {$match:{greetings:{$elemMatch:query}}}, 
    {$unwind:"$greetings"}, 
    {$match:{"greetings.hello":"world"}}, 
]).toArray() 

有了这个,你应该得到下面的输出想要创建一个可以生成您期望的文档的聚合管道,您应该始终在第一阶段开始查询。然后最终添加阶段来监控后续阶段的输出。

$unwind级的输出将是:

[{ 
    greetings:{hello:"world"} 
}, 
{ 
    greetings:{hello:"world", extra:"data"} 
}, 
{ 
    greetings:{hello:"world"} 
}, 
{ 
    greetings:{aloha:"mars"} 
}] 

现在,如果我们包括您所使用的第三个阶段,那么这将符合该有一个值{hello:"world"}并与精确值greetings键,将只能找到两个文件。所以你只会得到:

{ "greetings" : { "hello" : "world" } } 
{ "greetings" : { "hello" : "world" } } 
+0

你已经证实了我所担心的。如前所述,我知道最后阶段被解释为对平等的考验。我知道我可以手动将所有字段解压缩为完整的路径和值作为相等性测试,但这正是我不想做的事情,因为我的“查询”可以是任何东西。问题是,尽管最后一个匹配阶段在过滤逻辑中与第一阶段相同,但MongoDb需要两种不同的查询语法。解决方法;创建例程以将匹配查询解压缩为MongoDb应该首先提供的路径平等。 – user2257198

相关问题