[英]Elasticsearch in Python. How to get closes integer from search
我在大型索引数据库上使用elasticsearch。 其中一个查询需要查找整数值和字符串,例如:
s = Search(using=es, index="index1").extra(size=500) \
.query("match_phrase", name={"query": "john".casefold()})\
.query("match", age="46")
这将搜索包含“John white”和“46”的数据记录。 但是,如果年龄不正确,我想获得一个包含“John white”的记录和最接近“46”的年龄(假设我有这些记录,否则它将不返回任何内容)。
然而,上述查询仅返回年龄记录为“46”的记录。
在SO上已经存在类似的问题: 如何使用弹性搜索中的查询DSL找到最近/最接近的数字
但我不知道如何将JSON合并到我的查询中,因为我使用的是特定的python模块。
一个典型的例子就是我可以在字符串上使用模糊性。 但是我觉得在弹性搜索中,整数的模糊性是不可能的。
我建议使用基于脚本的排序来完成此操作,如下所述: https : //www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_script_based_sorting
在假设您只匹配名字的情况下工作 - 如果您想要完全匹配名称,我建议使用基于过滤器的匹配。 我在索引中使用了三个不同的“用户”,定义如下:
POST index1/_doc
{
"name": "John White",
"age": 46
}
POST index1/_doc
{
"name": "John White",
"age": 40
}
POST index1/_doc
{
"name": "John Black",
"age": 47
}
我发现使用Kibana的Dev Tools进行测试,然后将其转换为Python Elasticsearch DSL兼容格式,可以更轻松地编写更复杂的内容 - 所以在Kibana中,我最终想出了以下内容:
GET index1/_search
{
"query": {
"match_phrase": {
"name": {
"query": "john"
}
}
},
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "Math.abs(doc['age'].value - params.target_age)",
"params": {
"target_age": 46
}
},
"order": "asc"
}
}
}
注意使用差异的绝对值将给出最接近任一方向的值(即更年轻或更老)。 如果您的要求不同,可能需要进行一些调整。 只需在查询更改时调整参数,以适应不同的目标年龄。
经过测试和验证后,转换为Python Elasticsearch DSL非常简单 - 您可以使用“自动缩进”功能来平滑sort
的复杂性并将其直接放入现有语句中。
s = Search(using=es, index="index1").extra(size=500) \
.query("match_phrase", name={"query": "john".casefold()}) \
.sort({"_script":{"type":"number","script":{"lang":"painless","source": \
"Math.abs(doc['age'].value - params.target_age)", \
"params":{"target_age":46}},"order":"asc"}})
执行此操作将返回预期的响应:
<Response: [<Hit(index1/_doc/VR3e7WkBsHIsqLp6vfx_): {'name': 'John White', 'age': 46}>, <Hit(index1/_doc/Vx3f7WkBsHIsqLp6DPxM): {'name': 'John Black', 'age': 47}>, <Hit(index1/_doc/Vh3e7WkBsHIsqLp6yfxd): {'name': 'John White', 'age': 40}>]>
但是,如您所示,您想要最接近的值,我建议您将size参数更改为1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.