在mongodb $ match中,如何测试字段MATCHING,而不是字段EQUALING

时间:2016-04-07 20:17:03

标签: mongodb aggregation-framework

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

查询规范......

var query = {hello:"world"};

...可以使用MongoDb的本地节点驱动程序的find()操作来检索以下文档,其中查询'映射'被解释为匹配...

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

...等...

collection.find(query);

当与$ elemMatch一起使用时,同样的查询地图也可以被解释为匹配,以检索包含在像这些文档这样的数组中的匹配条目的文档......

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

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

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

...使用像[PIPELINE1] ......

这样的调用
collection.aggregate([
  {$match:{greetings:{$elemMatch:query}}},
]).toArray()

然而,尝试通过展开获取匹配问候的列表[PIPELINE2] ......

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

...使用任何匹配的条目生成文档中的所有数组条目,包括不匹配的条目(简化结果)......

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

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

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

不幸的是,PIPELINE3只生成以下条目,排除匹配的hello world条目以及额外的:" data",因为该条目并非严格等于' ;查询(简化结果)......

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

......我需要的是结果......

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

如何向PIPELINE2添加第二个$ match阶段,过滤问候字段与查询匹配的位置(并且可能还包含其他数据),而不是将结果限制为问候字段EQUALS查询的条目?

1 个答案:

答案 0 :(得分:0)

您在结果中看到的内容是正确的。你的方法有点不对劲。如果你想要你期望的结果,那么你应该使用这种方法:

{{"id":"857","name":"ALICARE}

有了这个,你应该得到以下输出:

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

每当你在MongoDB中使用[ {greetings:{hello:"world"}}, {greetings:{hello:"world"}}, {greetings:{"hello":"world","extra":"data"} ] 并希望创建一个产生预期文档的聚合管道时,你应该始终在第一阶段开始查询。然后最终添加阶段来监控后续阶段的输出。

aggregation阶段的输出将为:

$unwind

现在,如果我们包含您使用的第三个阶段,那么它将匹配具有值[{ greetings:{hello:"world"} }, { greetings:{hello:"world", extra:"data"} }, { greetings:{hello:"world"} }, { greetings:{aloha:"mars"} }] 的{​​{1}}密钥并且具有该确切值,它将在管道中找到仅两个文档。所以你只会得到:

greetings