2013-04-03 6 views
17

Мне нужно индексировать 3 уровня (или более) дочернего родителя. Например, уровни могут быть автором, книгой и персонажами из этой книги.Elasticsearch более глубокий уровень Родительские отношения (внук)

Однако при индексировании более двух уровней возникает проблема с has_child и has_parent запросами и фильтрами. Если у меня есть 5 осколков, я получаю около одной пятой результатов при запуске запроса «has_parent» на самом низком уровне (символы) или запрос has_child на втором уровне (книги).

Я полагаю, что книга индексируется осколком по его родительскому идентификатору и поэтому будет находиться вместе со своим родителем (автором), но персонаж будет проиндексирован на осколок, основанный на хеше идентификатора книги, что делает не обязательно соответствует фактическому осколку, на который была проиндексирована книга.

Итак, это означает, что весь персонаж книг того же автора не обязательно должен находиться в одном и том же осколке (на самом деле он порочит все преимущества родителя-родителя).

Я что-то не так? Как я могу это разрешить, так как мне действительно нужны сложные запросы, например, «что авторы писали с женскими персонажами».

Я безумная суть показывает проблему, по адресу: https://gist.github.com/eranid/5299628

Суть в том, что если у меня есть отображение:

"author" : {   
     "properties" : { 
    "name" : { 
     "type" : "string" 
    } 
     } 
    }, 
"book" : {   
     "_parent" : { 
    "type" : "author" 
     }, 
     "properties" : { 
    "title" : { 
     "type" : "string" 
    } 
     } 
    }, 

"character" : {  
     "_parent" : { 
    "type" : "book" 
     }, 
     "properties" : { 
    "name" : { 
     "type" : "string" 
    } 
     } 
    } 

и индекс 5 Осколков, я не могу делать запросы с " has_child»и "has_parent"

запрос:

curl -XPOST 'http://localhost:9200/index1/character/_search?pretty=true' -d '{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "has_parent": { 
      "parent_type": "book", 
      "query": { 
       "match_all": {} 
      } 
      } 
     } 
     ] 
    } 
    } 
}' 

возвращает только пятую (приблизительно) символов.

ответ

25

Вы правы, отношения между родителями и дочерними могут работать только в том случае, если все дочерние элементы данного родителя находятся в том же осколке, что и родительский. Elasticsearch достигает этого, используя родительский идентификатор в качестве значения маршрутизации. Он отлично работает на одном уровне. Тем не менее, он ломается на втором и последовательном уровнях. Когда у вас есть отношения родителя/ребенка/внука, родители маршрутизируются на основе своего идентификатора, дети маршрутизируются на основе родительских идентификаторов (работ), но затем внуки маршрутизируются на основе идентификаторов детей, и они попадают в неправильные осколки. Чтобы продемонстрировать это на примере, давайте предположим, что мы индексировать 3 документа:

curl -XPUT localhost:9200/test-idx/author/Douglas-Adams -d '{...}' 
curl -XPUT localhost:9200/test-idx/book/Mostly-Harmless?parent=Douglas-Adams -d '{...}' 
curl -XPUT localhost:9200/test-idx/character/Arthur-Dent?parent=Mostly-Harmless -d '{...}' 

Elasticsearch использует значение Douglas-Adams для расчета маршрута для документа Douglas-Adams - не удивительно здесь. Для документа Mostly-Harmless Elasticsearch видит, что у него есть родительский Douglas-Adams, поэтому он использует снова Douglas-Adams для расчета маршрутизации, и все хорошо - то же самое значение маршрутизации означает тот же осколок. Но для документа Arthur-Dent Elasticsearch видит, что у него есть родительский Mostly-Harmless, поэтому он использует значение Mostly-Harmless в качестве маршрутизации, а в результате документ Arthur-Dent попадает в неправильный осколок.

Решение этого заключается в том, чтобы явно указать маршрутизации значения для внуков, равного идентификатор прародителей:

curl -XPUT localhost:9200/test-idx/author/Douglas-Adams -d '{...}' 
curl -XPUT localhost:9200/test-idx/book/Mostly-Harmless?parent=Douglas-Adams -d '{...}' 
curl -XPUT localhost:9200/test-idx/character/Arthur-Dent?parent=Mostly-Harmless&routing=Douglas-Adams -d '{...}' 
+0

прохладный. Как я могу это указать? – eran

+4

с использованием параметра маршрутизации по URL. См. Раздел маршрутизации здесь - http://www.elasticsearch.org/guide/reference/api/index_/ – imotov

+0

Спасибо. Могу ли я также указать это в пост-данных? специально для bulk_index, где я хочу указать маршрутизацию для каждого документа? – eran

0

Для дедушки документы, вам нужно, чтобы получить _id как _routing. Для документов отца просто используйте _parent (grandpa._id) как _routing. Для детей docs просто используйте grandpa._id как _routing.

+0

Смущенный мной. –

Смежные вопросы