【发布时间】:2014-12-02 22:18:21
【问题描述】:
我想为以下查询创建一个 mongodb 索引:
{
"$and": [
{
"$or": [
{
"connector_name": {
"$options": "i",
"$regex": "plop"
}
},
{
"connector": {
"$options": "i",
"$regex": "plop"
}
},
{
"component": {
"$options": "i",
"$regex": "plop"
}
},
{
"resource": {
"$options": "i",
"$regex": "plop"
}
},
{
"domain": {
"$options": "i",
"$regex": "plop"
}
},
{
"perimeter": {
"$options": "i",
"$regex": "plop"
}
}
]
},
{
"$or": [
{
"event_type": {
"$eq": "check"
}
}
]
}
]
}
我尝试了以下索引创建失败:
第一个索引尝试:
db.events.ensureIndex({'event_type': 1});
db.events.ensureIndex({'connector_name': 1});
db.events.ensureIndex({'connector': 1});
db.events.ensureIndex({'component': 1});
db.events.ensureIndex({'resource': 1});
db.events.ensureIndex({'domain': 1});
db.events.ensureIndex({'perimeter': 1});
第二个索引尝试:
db.events.ensureIndex({'event_type': 1, 'connector_name': 1});
db.events.ensureIndex({'event_type': 1, 'connector': 1});
db.events.ensureIndex({'event_type': 1, 'component': 1});
db.events.ensureIndex({'event_type': 1, 'resource': 1});
db.events.ensureIndex({'event_type': 1, 'domain': 1});
db.events.ensureIndex({'event_type': 1, 'perimeter': 1});
第三个索引尝试:
db.events.ensureIndex(
{
'event_type': 1,
'connector_name': 1,
'connector': 1,
'component': 1,
'resource': 1,
'domain': 1,
'perimeter': 1,
})
每次在mongo explain query 之后,我都会查看“indexOnly”和“nscanned”字段,这意味着(据我所知)mongo 对我的索引的良好使用。但是,到目前为止,结果很差,我的查询仍然没有使用索引。经过我所有的尝试,我仍然不明白我的 mongodb 索引系统哪里错了。
【问题讨论】:
-
您正在使用不区分大小写的正则表达式匹配,这将始终导致完整的索引扫描(充其量)......并且使用
$or子句,nscanned值将加起来为基数您正在比较的所有字段中。您能否描述一下您实际需要搜索的内容 - 只是关键字,还是您需要在所有这些字段中进行子字符串匹配? -
通过这个查询,我想找到所有包含查询值的匹配文档,这里是 "plop" 。现在,我将尝试按照您的建议进行区分大小写的搜索,希望 mongo 将使用我的索引。事实上,这个查询的目的是在我的文档中执行搜索以及搜索引擎。这就是为什么我的搜索如此宽松。
-
我更改了查询,现在它看起来像 "$or": [ { "connector_name": { "$regex": "/^Sphinx.*/" } },...我之前描述的第三个索引模型,但索引搜索仍然无法正常工作