之间的功能区别是什么:
db.docs.find({ 'a.b': 'c' }, { 'a.$': 1 })
和
db.docs.find({ 'a.b': 'c' }, { 'a': { $elemMatch: { b: 'c' } } })
$ elemMatch是多余的吗?索引将如何变化?
答案 0 :(得分:10)
投影使用的差异有些微妙。在您的示例用法中,这些应该是等效查询(就索引使用而言),但$elemMatch
示例不必要地重复查询条件。对于此示例,$
投影将是更明智的选择。
文档中提到的一个重要差异是$
预测的array field limitation:
由于查询文档中只能出现一个数组字段,如果数组包含文档,要在这些文档的多个字段中指定条件,请使用$ elemMatch运算符。
关于以下投影算子差异的进一步说明......
$
) projection operator:限制查询结果中包含的数组字段的内容,以包含与查询文档匹配的第一个元素。
要求匹配的数组字段包含在查询条件
只能在查询条件
只能在投影中使用一次
$elemMatch
projection operator 限制查询结果中包含的数组字段的内容,使其仅包含与$ elemMatch条件匹配的第一个数组元素 。
不要求匹配数组在查询条件
可用于匹配嵌入文档的数组元素的多个条件
$elemMatch
query operator 请注意,还有一个$elemMatch
查询运算符执行类似的匹配,但在查询中而不是结果投影。看到这与$
投影结合使用并不罕见。
借用example from the docs,您可以同时使用两者:
db.students.find(
// use $elemMatch query operator to match multiple criteria in the grades array
{ grades: {
$elemMatch: {
mean: { $gt: 70 },
grade: { $gt: 90 }
}
}},
// use $ projection to get the first matching item in the "grades" array
{ "grades.$": 1 }
)
答案 1 :(得分:1)
如果单独使用$ elemMatch,则在查找投影中
$ elemMatch不会过滤文件(未应用的条件)
假设'学生'包含以下文件
{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] }
{ "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] }
{ "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }
{ "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] }
{ "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] }
{ "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }
{
"_id" : 7,
"semester" : 3,
"grades" : [
{
"grade" : 80,
"mean" : 75,
"std" : 8
},
{
"grade" : 85,
"mean" : 90,
"std" : 5
},
{
"grade" : 90,
"mean" : 85,
"std" : 3
}
]
}
{
"_id" : 8,
"semester" : 3,
"grades" : [
{
"grade" : 92,
"mean" : 88,
"std" : 8
},
{
"grade" : 78,
"mean" : 90,
"std" : 5
},
{
"grade" : 88,
"mean" : 85,
"std" : 3
}
]
}
以下查询将返回集合中的所有文档,
db.students.find({},{ grades: { $elemMatch: { mean: 90 } } } ).pretty()
其中as,查询下面只返回匹配的记录
db.students.find({"grades.mean":90},{"grades.$":1}).pretty()
我希望索引在任何一个查询中都没有任何区别