lab*_*day 3 python elasticsearch elasticsearch-dsl
我在使用Python 中的elasticsearch_dsl和elasticsearch库搜索嵌套文档时遇到问题。
我可以成功地对文档的顶级(即非嵌套)部分执行搜索,但是我搜索嵌套部分的所有尝试都因某种原因而失败。
我已经在 StackOverflow 和网络上搜索了使用 Python 搜索嵌套文档的权威指南,但一直在简短说明。
这是我正在使用的示例文档:
{"username": "nancy",
"codeData": [
{"code": "B1", "order": "2"},
{"code": "L4", "order": "1"}
]
}
Run Code Online (Sandbox Code Playgroud)
我在索引中有 7 个文档,我已将其映射如下:
request_body = {
"settings" : {
"number_of_shards": 5,
"number_of_replicas": 1
},
'mappings': {
'testNesting': {
'properties': {
'username': {'type': 'text'},
'codeData': {'type': 'nested',
'properties' :{
"code" : {"type":"text"},
"order" :{"type":"text"}
}
}
}
}
}
}
es.indices.create(index = "nest-test6", body = request_body)
Run Code Online (Sandbox Code Playgroud)
执行以下搜索工作正常:
s = Search(using = es).query("match", username = "nancy")
response = s.execute()
print(response.to_dict())
Run Code Online (Sandbox Code Playgroud)
现在,我想尝试在“codeData”中搜索代码 =“B1”的文档。
我已经在这个问题的底部列出了我尝试使用的来源。我希望这可以成为人们在尝试使用 Python 查询嵌套文档时可以参考的权威指南。
这是我迄今为止尝试过的:
q = Q("match", code = "L4")
s = Search(using = es, index = "nest-test6").query("nested", path = "codeData", query = q)
Run Code Online (Sandbox Code Playgroud)
以上导致传输错误(400,无法创建查询),然后在每个项目后列出查询本身并带有一堆 \n。
q = Q("match", **{"codeData.code"" : "L4"})
s = Search(using = es, index = "nest-test6").query("nested", path = "codeData", query = q)
Run Code Online (Sandbox Code Playgroud)
以上导致第 1 行出现语法错误。
s = Search(using = es, index = "nest-test6").query("nested", path = "lithologyData", query = **Q{"match":{ "lithology":"L4"}})
Run Code Online (Sandbox Code Playgroud)
以上也会导致语法错误。
我尝试了其他几种方法 - 但改变了我的数据结构,因此在上述文档的上下文中将它们列在此处没有意义。
我不知道如何查询这些嵌套对象。我觉得我遗漏了几条信息:
如果我缺少任何其他来源,我真的很感激有人指点我!
s1 = Search(using = es).query("match", username = "nancy")
q1 = Q("match", lithologyData__lithology = "L4")
q2 = Q("match", **{"lithologyData.lithology":"L4"})
s2 = Search(using = es, index = "nest-test6").query("nested", path = "lithologyData", query = Q("match",lithologyData__lithology="L4"))
s3 = Search(using = es, index = "nest-test6").query("nested", path = "lithologyData", query = q1)
s4 = Search(using = es, index = "nest-test6").query("nested", path = "lithologyData", query = q2)
response = s1.execute()
response2 = s2.execute()
response3 = s3.execute()
response4 = s4.execute()
Run Code Online (Sandbox Code Playgroud)
回应 1:有效
响应 2:失败:
TransportError(400, u'search_phase_execution_exception', u'failed to create query: {\n "nested" : {\n "query" : {\n "match" : {\n "codeData.code" : {\n "query" : "L4",\n "operator" : "OR",\n "prefix_length" : 0,\n "max_expansions" : 50,\n "fuzzy_transpositions" : true,\n "lenient" : false,\n "zero_terms_query" : "NONE",\n "auto_generate_synonyms_phrase_query" : true,\n "boost" : 1.0\n }\n }\n },\n "path" : "codeData",\n "ignore_unmapped" : false,\n "score_mode" : "avg",\n "boost" : 1.0\n }\n}')
Run Code Online (Sandbox Code Playgroud)
响应 3:失败:
TransportError(400, u'search_phase_execution_exception', u'failed to create query: {\n "nested" : {\n "query" : {\n "match" : {\n "codeData.code" : {\n "query" : "L4",\n "operator" : "OR",\n "prefix_length" : 0,\n "max_expansions" : 50,\n "fuzzy_transpositions" : true,\n "lenient" : false,\n "zero_terms_query" : "NONE",\n "auto_generate_synonyms_phrase_query" : true,\n "boost" : 1.0\n }\n }\n },\n "path" : "codeData",\n "ignore_unmapped" : false,\n "score_mode" : "avg",\n "boost" : 1.0\n }\n}')
Run Code Online (Sandbox Code Playgroud)
响应4:失败:
TransportError(400, u'search_phase_execution_exception', u'failed to create query: {\n "nested" : {\n "query" : {\n "match" : {\n "codeData.code" : {\n "query" : "L4",\n "operator" : "OR",\n "prefix_length" : 0,\n "max_expansions" : 50,\n "fuzzy_transpositions" : true,\n "lenient" : false,\n "zero_terms_query" : "NONE",\n "auto_generate_synonyms_phrase_query" : true,\n "boost" : 1.0\n }\n }\n },\n "path" : "codeData",\n "ignore_unmapped" : false,\n "score_mode" : "avg",\n "boost" : 1.0\n }\n}')
ElasticSearch_DSL py 上的 Github 问题
ElasticSearch_DSL Python 文档 - 尽管这很有用,但文档中没有一个嵌套搜索/查询的示例。
要查询嵌套字段,您似乎有正确的方法:
q = Q("match", codeData__code="L4")
s = Search(using=es, index="nest-test6").query("nested", path="codeData", query=q)
Run Code Online (Sandbox Code Playgroud)
__传递给 kwarg 中的任何内容Q都将在.内部转换为。或者,您始终可以依赖 python kwarg 扩展:
q = Q('match', **{"codeData.code": "L4"})
Run Code Online (Sandbox Code Playgroud)
这应该也能正常工作,你的例子只是"在那里有一个额外的,这就是它被python拒绝的原因。
| 归档时间: |
|
| 查看次数: |
1405 次 |
| 最近记录: |