MongoDB(3.0)聚合:多个匹配项与多个项目的一个匹配项
我正在从事一个项目,该项目要求我根据大量匹配(可能是100个)动态创建MongoDB查询。除了创建适当的索引外,我还想知道如何将匹配项构建到管道中是否重要。根据以下示例,其中一个示例的性能是否与另一个不同或更好 我假设示例2会缩小结果集,但会有更多调用?也许这就是示例1在幕后所做的事情 提前感谢您的帮助 示例1MongoDB(3.0)聚合:多个匹配项与多个项目的一个匹配项,mongodb,mongodb-query,Mongodb,Mongodb Query,我正在从事一个项目,该项目要求我根据大量匹配(可能是100个)动态创建MongoDB查询。除了创建适当的索引外,我还想知道如何将匹配项构建到管道中是否重要。根据以下示例,其中一个示例的性能是否与另一个不同或更好 我假设示例2会缩小结果集,但会有更多调用?也许这就是示例1在幕后所做的事情 提前感谢您的帮助 示例1 db.Test.aggregate( [ { $match: { item1: 'foo1', item2: 'foo2', item3: 'foo3' } } ])
db.Test.aggregate(
[
{ $match: { item1: 'foo1', item2: 'foo2', item3: 'foo3' } }
])
vs
示例2
db.Test.aggregate(
[
{ $match: { item1: 'foo1' } },
{ $match: { item2: 'foo2' } },
{ $match: { item3: 'foo3' } }
])
我怀疑这个问题是否重要,但如果相关,我将使用C#驱动程序进行实现。我在中找到了以下信息:
$match
+$match
合并
当一个$match
紧接着另一个$match
时,这两个阶段可以合并为一个$match,将条件与$and
组合在一起。例如,管道包含以下序列:
{ $match: { year: 2014 } },
{ $match: { status: "A" } }
然后,第二个$match阶段可以合并到第一个$match阶段,并形成一个$match阶段:
{ $match: { $and: [ { "year" : 2014 }, { "status" : "A" } ] } }
由此我可以说,在一行中使用多个$match
与在多个字段中使用单个$match
是相同的
但是,我不确定优化引擎为什么在这里添加
$和操作符。根据我的观点,它不应该是必要的,因此我认为它可以被忽略。有人能证实吗?我今天也在想同样的事情,偶然发现了罗曼的答案。虽然我想亲自看看这一点,这可以很容易地通过对两个集合的解释来实现
db.verpakking.explain().aggregate([
{ "$match": {type: "VERPAKT"} },
{ "$match": {ras: "CherryStar"} },
]);
这将导致以下输出:
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"$and" : [
{
"type" : "VERPAKT"
},
{
"ras" : "CherryStar"
}
]
},
"queryPlanner" : {
"plannerVersion" : NumberInt(1),
"namespace" : "denberk.verpakking",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"ras" : {
"$eq" : "CherryStar"
}
},
{
"type" : {
"$eq" : "VERPAKT"
}
}
]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"ras" : {
"$eq" : "CherryStar"
}
},
{
"type" : {
"$eq" : "VERPAKT"
}
}
]
},
"direction" : "forward"
},
"rejectedPlans" : [
]
}
}
}
],
"ok" : NumberInt(1)
}
当
db.verpakking.explain().aggregate([
{ "$match": {type: "VERPAKT", ras: "CherryStar"} },
]);
产出结果:
{
"waitedMS" : NumberLong(0),
"stages" : [
{
"$cursor" : {
"query" : {
"type" : "VERPAKT",
"ras" : "CherryStar"
},
"queryPlanner" : {
"plannerVersion" : NumberInt(1),
"namespace" : "denberk.verpakking",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"ras" : {
"$eq" : "CherryStar"
}
},
{
"type" : {
"$eq" : "VERPAKT"
}
}
]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"ras" : {
"$eq" : "CherryStar"
}
},
{
"type" : {
"$eq" : "VERPAKT"
}
}
]
},
"direction" : "forward"
},
"rejectedPlans" : [
]
}
}
}
],
"ok" : NumberInt(1)
}
正如您所看到的,除了“查询”部分(这是正常的,因为我们的查询是不同的)之外,这是完全相同的。这证明了无论使用两个独立的连续$match管道还是一个组合的$match管道,解析的查询都是完全相同的 有趣的问题…你找到答案了吗?我也想知道!我还假设$and是隐含的,所以它看起来确实不必要,但它背后可能还有另一个原因