我要执行一个像这样的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。
因此,我们将相关的文本可搜索字段title
与uuid
一起存储为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
文档是一个挑战。
考虑到上述情况和局限性,如何有效解决此问题?