2013-04-03 16 views
17

Çocuk-ebeveynden 3 seviyeyi (veya daha fazlasını) indekslemeliyim. Örneğin, seviyeler bir yazar, bir kitap ve bu kitaptaki karakterler olabilir. Ancak, iki düzeyden fazla indekslenirken, has_child ve has_parent sorguları ve filtreleriyle ilgili bir sorun var demektir. 5 tane kırıcıma sahip olursam, en düşük düzeyde (karakter) bir "has_parent" sorgusu çalıştırırken sonuçların beşte birini veya ikinci düzeydeki (kitaplar) bir has_child sorgusunu alırım.Elasticsearch deeper level Ebeveyn-çocuk ilişkileri (torun)

Tahminimce bir kitap, ebeveyn kimliğiyle bir parçaya endekslenir ve böylece ebeveyniyle (yazar) birlikte bulunur, ancak bir karakter, kitap kimliğinin karmasına dayalı olarak bir dizgeye endekslenir. zorunlu olarak kitap endeksli gerçek ile uyumlu değildir. Bu, aynı yazarın tüm kitaplarının mutlaka aynı parçada yer alması anlamına gelmediği anlamına gelir (tüm çocuk-ebeveyn avantajını sakatlamak gibi).

Yanlış bir şey yapıyorum? Örneğin, "yazarların kadın karakterleri olan kitapları yazdığı" gibi karmaşık sorgular için gerçekten ihtiyacım olduğu için bunu nasıl çözebilirim?

deli de, sorunu gösteren bir özü:

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

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

ve 5 kırıkları endeksi, ben "sorguları yapamaz: Ben bir eşleme varsa o, https://gist.github.com/eranid/5299628

Alt çizgidir has_child" ve "has_parent"

sorgusu:

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

, karakterlerin yalnızca beşte birini (yaklaşık) döndürür.

cevap

25

Doğru, ebeveyn/çocuk ilişkisi yalnızca, belirli bir ebeveyni olan tüm çocuklar ebeveynleriyle aynı kökende yaşadığında çalışabilir. Elasticsearch, bunu ebeveyn kimlik değerini bir yönlendirme değeri olarak kullanarak gerçekleştirir. Bir düzeyde harika çalışıyor. Bununla birlikte, ikinci ve ardışık seviyelerde kırılır. Ebeveyn/çocuk/torun ilişkisine sahip olduğunuzda ebeveynler kimliklerine göre yönlendirilirler, çocuklar ana kimliklere (çalışmalara) göre yönlendirilir, ancak torunlar çocuk kimliklerine göre yönlendirilir ve yanlış parçalara ayrılır. Bir örnek üzerinde göstermek için, en biz 3 endeksleme belgeler olduğunu varsayalım:

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 belgenin Douglas-Adams güzergahına hesaplamak için değer Douglas-Adams kullanır - hayır sürpriz burada. Elasticsearch, Mostly-Harmless numaralı belge için, Douglas-Adams numaralı ana bağlantıya sahip olduğunu gördüğü için, yönlendirmeyi hesaplamak için yeniden Douglas-Adams kullanır ve her şey iyidir - aynı yönlendirme değeri aynı eğim anlamına gelir. Ancak, Arthur-Dent belgesine göre Elasticsearch, Mostly-Harmless numaralı üstbilgiye sahip olduğunu görüyor, bu nedenle Mostly-Harmless değerini bir yönlendirme olarak kullanıyor ve sonuç olarak Arthur-Dent numaralı belge hatalı bir parçada sona eriyor.

Bunun çözümü açıkça grandparent ait id eşit torunları için yönlendirme değerini belirtmektir:

dede docs için
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

cool. Bunu nasıl belirleyebilirim? URL'de yönlendirme parametresini kullanarak – eran

+4

. Yönlendirme bölümünü buradan görebilirsiniz - http://www.elasticsearch.org/guide/reference/api/index_/ – imotov

+0

Teşekkürler. Bunu bir şekilde veri sonrası bir şekilde de belirleyebilir miyim? Özellikle her bir doküman için yönlendirme belirtmek istediğim bulk_index için? – eran

0

, sen _routing olarak _ID almak gerekir. Baba dokümanları için _parent (grandpa._id) öğesini _routing olarak kullanın. Çocuklar için dokümanlar, grandpa._id dosyasını _routing olarak kullanın.

+0

Bana şaşkın. –