MongoDB中的$elemMatch查询

6
我可以帮助您进行翻译。以下是您需要翻译的内容:

我有一个名为“name”的集合,其中包含两个文档,结构如下:

文档1:

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

文档2:

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

由于我对MongoDB还不熟悉,我正在尝试找出使用$elemMatch运算符和不使用它的区别。基本上,我正在查询并查找名为AAA且年龄为10岁的第一个文档(文档1)。因此,使用$elemMatch,我的查询如下:

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

这个查询完全正常,但我的问题是,当我可以像这样查询时,为什么需要使用此查询:
db.name.find({b:{name:"AAA",age:10}})

我相信使用$elemMatch一定有其原因,只是想找出其中的区别。提前感谢回复!!!
2个回答

6
关键区别在于第二个查询(不带$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
第二个查询匹配整个嵌入文档 db.name.find({b:{name:"AAA",age:10}}),但不是 db.name.find({"b.name":"AAA","b.age":10})。因此,在 OP 的用例中,第二个查询在理论上是 $elemMatch。 - s7vr

2
另一个重要的区别是Mongo如何使用索引。如果我们声明了多键合成索引:

Original Answer翻译成:"最初的回答"

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

And we execute this:

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

we get:

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

If we execute this:

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
  }
})

根据我非专业的测试,这似乎更快。

原始答案:Original Answer


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接