如何一起使用mongodb和elasticsearch优化此查询?

时间:2019-03-23 08:10:03

标签: python mongodb elasticsearch

我要执行一个像这样的mongodb查询。

query1 = {
        'source': source,
        'expiration_date': {
            '$gte': datetime.strftime(datetime.now(tz=tz), '%Y-%m-%d')
        },
        'low_performer': {
            '$nin': [utm_source]
        },
        '$text': {
                '$search': "positive_keyword -negative_keyword"
        }

}

result = collection.find(query1).limit(some_limit)
# feed the result to XML templating engine 

但是由于mongodb文本搜索中的某些限制,我需要将文本搜索部分移入elasticsearch。

因此,我们将相关的文本可搜索字段titleuuid一起存储为elasticsearch索引的_id

现在,直接的方法是

query2 = {
        'source': source,
        'expiration_date': {
            '$gte': datetime.strftime(datetime.now(tz=tz), '%Y-%m-%d')
        },
        'low_performer': {
            '$nin': [utm_source]
        }
}

result = collection.find(query2, {'uuid': 1})
uuids = (i['uuid'] for i in result)
# Can't apply limit yet, as text searching in es is still pending 

client = Elasticsearch()

response = client.search(
    index="my-index",
    body={
      "query": {
        "bool": {
          "must": [{"match": {"title": "positive_keyword"}}],
          "must_not": [{"match": {"title": "negative_keyword"}}],
          "filter": [{"term": {"_id": uuids}}]
        }
      }
    }
)

uuids = (hit['_id'] for hit in response['hits']['hits'])

result = collection.find({'_id': {'$in': uuids}}).limit(some_limit)
# feed it to XML templating engine

此解决方案有多个缺点。

1)query1能够将结果传递给处理器,而query2需要进行评估,而uuid则需要提取。尽管生成器可以提供一些帮助,但这可能是一项开销。

2)uuids是> 1M uuid的集合,因此,针对此列表在es中查找每个文档的成本都很高。

3)默认情况下,elasticsearch应该返回大约10k个匹配项。因此,在有限的内存中返回1M文档是一个挑战。

考虑到上述情况和局限性,如何有效解决此问题?

0 个答案:

没有答案