MongoDB按部分文本搜索时的快速查询

MongoDB按部分文本搜索时的快速查询,mongodb,indexing,Mongodb,Indexing,我的数据库很小,有200万个电话记录 当我执行: db.getCollection('calls').find({ 'IsIncoming':true,'DateCreated':{'$gte':ISODate('2010-12-02T02:26:22.478Z')},'CallerIdNum':“2545874578” }).limit(100).count({}) 这是一种晚餐快餐,需要95毫秒注意,IsIncoming、DateCreted和CallerIdNum都有索引。每次我使用这些

我的数据库很小,有200万个电话记录

当我执行:

db.getCollection('calls').find({
'IsIncoming':true,'DateCreated':{'$gte':ISODate('2010-12-02T02:26:22.478Z')},'CallerIdNum':“2545874578”
}).limit(100).count({})
这是一种晚餐快餐,需要95毫秒注意,
IsIncoming
DateCreted
CallerIdNum
都有索引。每次我使用这些字段搜索时,搜索速度都非常快

当我搜索包含部分文本的内容时,速度非常慢。例如,此查询现在需要25秒:

db.getCollection('calls').find({
'IsIncoming':true,'DateCreated':{'$gte':ISODate('2010-12-02T02:26:22.478Z')},'CallerIdNum':/2545874/
}).limit(100).count({})
我知道原因是因为我正在
CallerIdNum
中搜索。如果我像第一次查询那样提前知道完整的呼叫者id,那么它会很快

问题:
我希望最后一个查询执行得更快。我知道这可能是不可能的,而获得出色性能的唯一方法是通过整个CallerIdNum进行搜索。但也许/希望我错了,有人能帮我找到一种更快执行上一次查询的方法。

这里的问题是,您正在搜索呼叫者ID号的子字符串
/2545874/
。不可搜索,通常不能使用索引。假设您确实需要以该前缀开头的数字,则使用此sargable版本:

db.getCollection('calls').find({  
    'IsIncoming':true, 'DateCreated' : { '$gte': ISODate('2010-12-02T02:26:22.478Z') }, 'CallerIdNum' : /^2545874/
}).limit(100).count({})

您可能还希望在所有三个字段上添加一个复合索引,尽管至少我上面给出的查询版本可以使用涉及
CallerIdNum
字段的索引。

第一种情况下您有一个复合索引,对吗?出于好奇,使用
^
$
可以获得更好的性能,但您可能知道这一点。@Minsky问得好,我只知道数据库的基本知识。我用这个查询创建了索引
db.calls.createIndex({CallerIdNum:1})
。我怎么知道它是不是一个复合索引?你的瓶颈显然是正则表达式。但是想象一下索引和书中的索引是一样的。当mongo查找该索引时,它会找到值(文档id),但不知道其他字段!然后它必须从索引返回到书(只知道它能读得更快),并获取文档。。;如果您知道形状,可能会发生一些变化,
/\d\d\d31562456\d/
您如何支持不能使用索引的声明?我不认为这是真的。如果呼叫者Id字段有一个B树索引,那么它只能使用前缀。非常好,谢谢Tim。如果我想搜索介于两者之间的文本,我想这是不可能的,对吗?@TonoNam您当前的查询在逻辑上已经这样做了,只是速度不够快。如果执行子字符串操作,可能会更快。此外,Mongo可能还有其他类型的索引,除了B树。你已经回答了这个问题,它很棒。一旦它允许我,我就接受它。我只是出于好奇而问,这样我可以学到更多。然后我会搜索其他类型的索引。再次感谢。