2017-07-19 85 views
1

我有一个约100万个文档(主要是电影)的集合,我在一个字段上创建了一个文本索引。几乎所有的搜索都可以正常工作:小于20ms可以得到结果。例外情况是,当一个搜索非常频繁的术语时,它可以持续高达3000毫秒! 例如,MongoDB:搜索非常频繁的术语时缓慢的文本搜索

,如果我的收藏(只有40的文件的话),它持续时间为1ms

如果我搜索“电影”(750个000文件的话)中搜索“纸浆”,它持续3000ms。 分析请求时,explain('executionStats')显示扫描所有'电影'文档。我尝试了许多索引,排序+限制和暗示,但所有750 000个文档仍然被扫描,结果仍然很慢...

有没有一种策略能够更快地搜索数据库中非常频繁的术语?

+0

这是正常现象,想想吧。文本索引比实际的集合大得多,因为每个单词都被索引。因此,搜索比总集合更大的索引的一部分将导致mongoDB扫描实际集合本身。如果你能够强制它使用索引,它会更慢。为了更快获得结果,您可能会限制结果? –

+0

我试图限制,但因为我想要一个排序的输出,所有文档仍然被扫描......逻辑上。 – Eric

回答

0

我最终通过编码像这样做我自己的停用词列表:

import pymongo 
from bson.code import Code 

# NB max occurences of a word in a collection after what it is considerated as a stop word. 
NB_MAX_COUNT = 20000 
STOP_WORDS_FILE = 'stop_words.py' 

db = connection to the database... 

mapfn = Code("""function() { 
    var words = this.field_that_is_text_indexed; 
    if (words) { 
     // quick lowercase to normalize per your requirements 
     words = words.toLowerCase().split(/[ \/]/); 
     for (var i = words.length - 1; i >= 0; i--) { 
      // might want to remove punctuation, etc. here 
      if (words[i]) {  // make sure there's something 
       emit(words[i], 1); // store a 1 for each word 
      } 
     } 
    } 
};""") 

reducefn = Code("""function(key, values) { 
    var count = 0; 
    values.forEach(function(v) { 
     count +=v; 
    }); 
    return count; 
};""") 

with open(STOP_WORDS_FILE,'w') as fh: 
    fh.write('# -*- coding: utf-8 -*-\n' 
      'stop_words = [\n') 

    result = db.mycollection.map_reduce(mapfn,reducefn,'words_count') 
    for doc in result.find({'value':{'$gt':NB_MAX_COUNT}}): 
     fh.write("'%s',\n" % doc['_id']) 

    fh.write(']\n')