Запрос многоуровневых вложенных полей в Elastic Search
Я новичок в 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.
но я не могу понять, как запросить на основе концепций вложенного поля.
В документации ES указано, что
Многоуровневая вложенность автоматически поддерживается и обнаруживается, в результате чего внутренний вложенный запрос автоматически соответствует соответствующему уровню вложенности (а не корневому), если он существует в другом вложенном запросе.
Итак, я попытался построить запрос в следующем формате:
query2 = {
"nested": {
"path": "concepts",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"concepts.name": "concept1"}
},
{
"range": {"concepts.score": {"gt": 0}}
}
]
}
}
}
}
который дал 0 результатов.
Я не могу понять, чего не хватает, и я не нашел ни одного примера с запросами, основанными на двух уровнях вложенности.
3 ответа
Хорошо, попробовав тон комбинаций, я наконец получил его, используя следующий запрос:
query3 = {
"nested": {
"path": "subjects",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"subjects.concepts.name": "concept1"}
}
]
}
}
}
}
Таким образом, атрибут вложенного пути (subject) всегда один и тот же, независимо от уровня вложенного атрибута, и в определении запроса я использовал полный путь атрибута (subject.concepts.name).
Выстрел в темноте, так как я не пробовал это лично, но пробовали ли вы полностью квалифицированный путь к Концепциям?
query2 = {
"nested": {
"path": "subjects.concepts",
"score_mode": "avg",
"query": {
"bool": {
"must": [
{
"text": {"subjects.concepts.name": "concept1"}
},
{
"range": {"subjects.concepts.score": {"gt": 0}}
}
]
}
}
}
}
У меня есть вопрос к ответу JCJS. почему ваше отображение не должно нравиться это?
mapping = {
"subjects": {
"type": "nested",
"properties": {
"concepts": {
"type": "nested"
}
}
}
}
Я пытаюсь определить два отображения типов, может быть, не работает, но сглаживать данные; Я думаю, что мы должны вкладываться во вложенные свойства..
Наконец... если мы используем это отображение, вложенный запрос должен выглядеть так...
{
"query": {
"nested": {
"path": "subjects.concepts",
"query": {
"term": {
"name": {
"value": "concept1"
}
}
}
}
}
}
Это жизненно важно для использования full path
для атрибута пути... но не для термина ключ может быть полным или относительным путем.