【发布时间】:2014-02-28 09:40:10
【问题描述】:
我在为我的查询创建索引时遇到问题,并且在网络上找不到任何类似的解决方案,所以也许你们中的一些人会帮助我。
为了简化问题,假设我们有具有某些属性的电话,
{
"type":"Samsung",
"model":"S3",
"attributes":[{
"value":"100",
"name":"BatteryLife"
},{
"value":"200$",
"name":"Price"
}
}
带索引:{"type":1, "attributes.value":1}
每种类型都有数百万部手机,我想查找具有给定属性的给定类型的手机,我的查询如下所示:
db.Phone.aggregate([
{ "$match" : { "type" : "Samsung"}} ,
{ "$match" : { "attributes" : { "$all" : [
{ "value" : "100", "name" : "BatteryLife" } ,
{ "value" : "200$", "name" : "Price"}
]}
}
}
])
而且它有效! 问题是这个查询效率很低,因为它只使用我的索引的第一部分,即“类型”(我有数百万个每种类型的电话),并且不使用“attributes.value”部分(类型+ attributes.value 几乎是唯一的,因此会显着降低复杂性)。
@编辑 感谢 Neil Lunn,我知道这是因为 index 仅在我的第一场比赛中使用,所以我必须更改我的查询。
@Edit2 我想我找到了解决方案:
db.Phone.aggregate([
{$match: {
$and: [
{type: "Samsung"},
{attributes: {
$all: [
{ "value":"100", "type" : "BatteryLife" },
{ "value":"200$", "type" : "Price" }
]
}}
]}
}])
+db.Phone.ensureIndex({type:1, attributes:1}),似乎有效。我想我们现在可以关门了。感谢您提供有关 $match 的提示。
【问题讨论】:
-
对于覆盖索引,您需要将查询中使用的所有字段按顺序和包含在内。这里的主要问题是您正在编写 multiple 匹配阶段,而所有条件都应仅在开始时处于 one 阶段。在第一次匹配之后,就不再使用 index。虽然您的问题中有很多信息,但它并没有描述您真正想要解决的问题。这是此处提出问题的最佳格式。
-
解释我真正的问题太长了,但数据结构完全一样。感谢提示索引仅在第一场比赛中使用,我不知何故错过了。
-
试图向您指出您根本没有解释您的问题。你已经被标记为接近投票。避免这种情况的最佳方法是将您的问题重新表述为人们可以解决的问题。
-
我已经编辑了我的帖子,希望现在更清楚了。如果可能的话,我将尝试重新调整我的查询并将“type”和“attribute.value”放在一个匹配项中。请不要关闭这个话题。
-
您应该从查询中删除 $and - 这里不需要它,因为“,”已经是“和”等价的。此外,您的查询语法可能不是您想要的。怀疑您打算使用 $elemMatch 来获得正确的结果。
标签: mongodb indexing aggregation-framework