首页 > 解决方案 > 有没有办法提高 MongoDB 的全文搜索性能?

问题描述

我正在使用 MongoDB Atlas 来提供大约 110k 的运动员数据。

每个文档都包含一个name字段和一个name_foreign字段,该字段的名称采用 MongoDB 的全文搜索不支持的不同语言。在我的 Python 应用程序中,我使用 Pymongo 根据球员的英文和外语姓名返回搜索结果。我创建了一个索引,以便我可以根据搜索查询对搜索结果进行评分。

db.players.create_index([ ("name", TEXT), ('name_foreign', TEXT) ])

在我的 Python 应用程序中,我检测输入字符串,每当它使用其他语言时,我将字符串标记化,然后将其输入到find查询中(name_foreign数据库中的字段已经标记化,以便全文搜索工作)。

我的 GET 玩家端点

try:
    # transform query if it's non-eng
    if detect(name) == '...': # some language
        query = ''
        for ch in name:
            if ch != ' ':
                query += ch + ' '
        query = query.rstrip()
    else:
        query = name
    players = list(db.players.find({ "$text": { "$search": query }},
                { 'score': { "$meta": "textScore" }}))
    players.sort(key = lambda k: (k['score'], k['reputation']), reverse = True)
    # Return results based on the input query
    return jsonify({ 'result': [player_to_dict(player) for player in players][:4]})

except: ...

我终于返回了搜索的前 4 个结果。这适用于英语,全文搜索适用于它。但是,当我使用另一种语言时,它适用于短名称,但是当名称变长一点时,它会崩溃,给我一个内存泄漏错误。

2019-11-28T21:51:47.301318+00:00 heroku[web.1]: Process running mem=799M(156.2%)
2019-11-28T21:51:47.301318+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)

当数据低于 10k 时,这种方法效果很好。现在它大约有 110k,看来我需要一种更好的方法来做到这一点。

我是这种东西的新手,我真的很想听听有经验的 MongoDB 用户的一些想法,并最终让它更好地工作。

提前致谢!

标签: mongodbmongodb-queryfull-text-search

解决方案


为了减少您正在使用的内存,您可以要求 mongo 为您进行排序,然后获得前 4 个结果。这样,您就不会将所有结果加载到内存中、对它们进行排序并且只使用前 4 个。

from bson import SON
cur = collection.aggregate([
    {
        "$match":{
            "$text": {
                "$search": "foo"
            }
        }
    },
    {
        "$addFields": {
            "textScore": {"$meta": "textScore"}
        }
    },
    { # best score and reputation at the top:
        "$sort": SON([("textScore", -1), ("reputation", -1)]) # must use SON and not a dict because the order of the sort matters here
    },
    {
        "$limit": 4
    }   
])

list(cur) # get top 4 results from the sort

Mongo 对排序后的限制阶段进行了特殊优化。您实际上并不需要对 110k 文档进行排序来选择 4 个文档,因此这也将比在您身边进行操作要快得多。


推荐阅读