我是Elastic Search和非SQL范例的新手。 我一直在关注ES教程,但有一件事我无法工作。
在下面的代码中(我使用PyES与ES进行交互)我创建了一个包含嵌套字段(主题)的单个文档,其中包含另一个嵌套字段(概念)。
from pyes import *
conn = ES('127.0.0.1:9200') # Use HTTP
# Delete and Create a new index.
conn.indices.delete_index("documents-index")
conn.create_index("documents-index")
# Create a single document.
document = {
"docid": 123456789,
"title": "This is the doc title.",
"description": "This is the doc description.",
"datepublished": 2005,
"author": ["Joe", "John", "Charles"],
"subjects": [{
"subjectname": 'subject1',
"subjectid": [210, 311, 1012, 784, 568],
"subjectkey": 2,
"concepts": [
{"name": "concept1", "score": 75},
{"name": "concept2", "score": 55}
]
},
{
"subjectname": 'subject2',
"subjectid": [111, 300, 141, 457, 748],
"subjectkey": 0,
"concepts": [
{"name": "concept3", "score": 88},
{"name": "concept4", "score": 55},
{"name": "concept5", "score": 66}
]
}],
}
# Define the nested elements.
mapping1 = {
'subjects': {
'type': 'nested'
}
}
mapping2 = {
'concepts': {
'type': 'nested'
}
}
conn.put_mapping("document", {'properties': mapping1}, ["documents-index"])
conn.put_mapping("subjects", {'properties': mapping2}, ["documents-index"])
# Insert document in 'documents-index' index.
conn.index(document, "documents-index", "document", 1)
# Refresh connection to make queries.
conn.refresh()
我可以查询主题嵌套字段:
query1 = {
"nested": {
"path": "subjects",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"subjects.subjectname": "subject1"}
},
{
"range": {"subjects.subjectkey": {"gt": 1}}
}
]
}
}
}
}
results = conn.search(query=query1)
for r in results:
print r # as expected, it returns the entire document.
但我无法弄清楚如何根据 concepts 嵌套字段进行查询。
ES documentation指的是
自动支持并检测多级嵌套, 导致内部嵌套查询自动匹配相关 嵌套级别(而不是root)如果它存在于另一个嵌套查询中。
因此,我尝试使用以下格式构建查询:
query2 = {
"nested": {
"path": "concepts",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"concepts.name": "concept1"}
},
{
"range": {"concepts.score": {"gt": 0}}
}
]
}
}
}
}
返回0结果。
我无法弄清楚缺少什么,我没有找到任何基于两个嵌套级别的查询示例。
答案 0 :(得分:12)
好的,在尝试了组合音后,我终于使用以下查询得到了它:
query3 = {
"nested": {
"path": "subjects",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"subjects.concepts.name": "concept1"}
}
]
}
}
}
}
因此,无论嵌套属性级别如何,嵌套的路径属性( subject )始终是相同的,并且在查询定义中我使用了属性的完整路径( subject.concepts.name )。
答案 1 :(得分:1)
在黑暗中拍摄,因为我没有尝试过这个,但你是否尝试过完全合格的概念路径?
query2 = {
"nested": {
"path": "subjects.concepts",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"subjects.concepts.name": "concept1"}
},
{
"range": {"subjects.concepts.score": {"gt": 0}}
}
]
}
}
}
}
答案 2 :(得分:0)
我对JCJS的回答有一些疑问。为什么你的映射不应该这样?
mapping = {
"subjects": {
"type": "nested",
"properties": {
"concepts": {
"type": "nested"
}
}
}
}
我尝试定义两种类型映射可能不起作用,但是是扁平数据;我认为我们应该嵌套在嵌套属性中。
最后......如果我们使用这个映射,嵌套查询应该是这样的......
{
"query": {
"nested": {
"path": "subjects.concepts",
"query": {
"term": {
"name": {
"value": "concept1"
}
}
}
}
}
}
将full path
用于路径属性至关重要...但对于术语密钥,不能是全路径或相对路径。