MongoDB中的$ elemMatch查询

时间:2017-01-18 17:09:09

标签: mongodb mongodb-query crud

我有一个集合'name',其中包含2个结构文档:

doc 1:

    {
    a: 1
    b : [{name:"AAA",age:10},
         {name:"BBB",age:12},
         {name:"CCC",age:13}]
    }

doc 2:

    {
    a: 2
    b : [{name:"DDD",age:14},
         {name:"EEE",age:15},
         {name:"FFF",age:16}]
    }

由于我是MongoDB的新手,我试图找到使用$ elemMatch运算符而不使用它的区别。基本上我正在尝试查询并找到名为AAA且年龄为10的第一个doc(doc 1)。所以使用$ elemMatch,我的查询看起来像这样:

db.name.find({b: {$elemMatch :{name:"AAA",age:10}}})

这个查询工作得很好,但我的问题是当我可以这样查询时需要使用这个查询:

db.name.find({b:{name:"AAA",age:10}})

我确信$ elemMatch应该有一些原因,只是想找到差异。在此先感谢您的回复!!!

2 个答案:

答案 0 :(得分:3)

关键区别在于第二个查询(没有$elemMatch)只会匹配b数组中仅包含这两个字段的元素,并且只能按此顺序匹配。

因此第一个查询将匹配以下两个文档,但第二个查询不会:

{
a: 1
b: [{name: "AAA", age: 10, city: 'New York'},
    {name: "BBB", age: 12, city: 'Paris'},
    {name: "CCC", age: 13, city: 'London'}]
}

{
a: 1,
b: [{age: 10, name: "AAA"},
    {name: "BBB", age: 12},
    {name: "CCC", age: 13}]
}

答案 1 :(得分:0)

另一个重要的区别是Mongo如何使用索引。

如果我们声明了一个多键复合索引:

db.name.createIndex({ "b.name": 1, "b.age": 1 })

我们执行以下操作:

db.name.explain().find({
  b: {
    name: "DDD",
    age: 14
  }
})

我们得到:

"winningPlan" : {
  "stage" : "COLLSCAN",

如果执行此操作:

db.name.explain().find({
  b: {
    $elemMatch: {
      name: "DDD",
      age: 14
    }
  }
})

我们得到:

"winningPlan" : {
  "stage" : "FETCH",
  "inputStage" : {
    "stage" : "IXSCAN",

但是如果我们在数组中有一个简单的多键索引:

db.name.createIndex({b: 1})

以上索引将在此查询中使用:

db.name.explain().find({
  b: {
    name: "DDD",
    age: 14
  }
})

在我非常不专业的分析测试下,这看起来更快。