2013-07-08 10 views
7

Bir belgeyi elastik aramada dizine eklemenin en iyi yolunu bulmaya çalışıyorum. Bazı alanlar içeren bir belge doktor var:Elastik aramada iç içe geçmiş türlerle çapraz nesne arama davranışı nasıl önlenir

Doc 
    created_at 
    updated_at 
    field_a 
    field_b 

Ama Doktor ayrıca bireysel kullanıcılara özgü bazı alanları olacaktır. Örneğin, field_x, kullanıcı 1 için 'A' değerine sahip olacaktır ve field_x, kullanıcı 2 için 'B' değerine sahip olacaktır. Her bir doküman için, çok sınırlı sayıda kullanıcı olacaktır (tipik olarak 2, en fazla ~ 10). Bir kullanıcı field_x'de arama yaptığında, onlara ait olan değeri aramalıdır. ES'de yuvalanmış türleri araştırıyorum.

Doc 
    created_at 
    updated_at 
    field_x: [{ 
    user: 1 
    field_x: A 
    },{ 
    user: 2 
    field_x: B 
    }] 

Kullanıcı 1, "A" değeri için field_x üzerinde arama yaptığında, bu dokümanın bir isabetle sonuçlanması gerekir. Ancak, kullanıcı 1 'B' değerine göre arama yapmamalıdır. Ancak

, according to the docs: sorunlardan

Bir dokümana birkaç kez meydana iç nesneleri indeksleme “çapraz nesne” Arama maç bir yolu var mı

oluşacak olmasıdır Bu davranışı iç içe türlerle önlemek veya başka bir tür keşfetmem mi gerekiyor?

Bu tür sorguların performansıyla ilgili ek bilgiler çok değerli olabilir. Sadece dokümanları okumaktan, iç içe geçmiş sorguların, normal sorgularla ilgili performans açısından çok farklı olmadığını belirtmiştir. Eğer bu deneyimin gerçek deneyimi varsa, bunu duymak isterim.

cevap

5

İç içe tür, aradığınız şeydir ve performans konusunda çok fazla endişelenmeyin.

belgelerinizi dizine önce, belgeler için eşleme ayarlamak gerekir:

curl -XDELETE localhost:9200/index 
curl -XPUT localhost:9200/index 
curl -XPUT localhost:9200/index/type/_mapping -d '{ 
    "type": { 
     "properties": { 
      "field_x": { 
       "type": "nested", 
       "include_in_parent": false, 
       "include_in_root": false, 
       "properties": { 
        "user": { 
         "type": "string" 
        }, 
        "field_x": { 
         "type": "string", 
         "index" : "not_analyzed" // NOTE* 
        } 
       } 
      } 
     } 
    } 
}' 

* not: saha gerçekten "A" ve "B" gibi sadece tekil harfler içeriyorsa, 'don Alanı analiz etmek istemezseniz, aksi takdirde elasticsearch bu tekil harf "kelimeleri" kaldıracaktır. Bu sadece sizin örneğinizdeyseniz ve gerçek belgelerinizde doğru kelimeleri arıyorsanız, bu satırı kaldırın ve elasticsearch'in alanı analiz etmesine izin verin. Sonra

, endeks belgeleriniz:

curl -XPUT http://localhost:9200/index/type/1 -d ' 
{ 
    "field_a": "foo", 
    "field_b": "bar", 
    "field_x" : [{ 
     "user" : "1", 
     "field_x" : "A" 
    }, 
    { 
     "user" : "2", 
     "field_x" : "B" 
    }] 
}' 

Ve sorguyu çalıştırın:

curl -XGET localhost:9200/index/type/_search -d '{ 
    "query": { 
     "nested" : { 
      "path" : "field_x", 
      "score_mode" : "avg", 
      "query" : { 
       "bool" : { 
        "must" : [ 
         { 
          "term": { 
           "field_x.user": "1" 
          } 
         }, 
         { 
          "term": { 
           "field_x.field_x": "A" 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
}'; 

Bu sorgulama, Ancak

{"took":13,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":1.987628,"hits":[{"_index":"index","_type":"type","_id":"1","_score":1.987628, "_source" : 
{ 
    "field_a": "foo", 
    "field_b": "bar", 
    "field_x" : [{ 
     "user" : "1", 
     "field_x" : "A" 
    }, 
    { 
     "user" : "2", 
     "field_x" : "B" 
    }] 
}}]}} 

sonuçlanacaktır

curl -XGET localhost:9200/index/type/_search -d '{ 
    "query": { 
     "nested" : { 
      "path" : "field_x", 
      "score_mode" : "avg", 
      "query" : { 
       "bool" : { 
        "must" : [ 
         { 
          "term": { 
           "field_x.user": "1" 
          } 
         }, 
         { 
          "term": { 
           "field_x.field_x": "B" 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
}'; 

herhangi bir sonuç

{"took":6,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}} 
+0

Bu büyük bir cevaptır döndürmez. Tam olarak aradığım şey. İyiliğin için teşekkür ederim. – Brad

+0

Bu eski bir cevaptır, [belgelere bakın] (https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-put-mapping.html) haritalandırma URL'sinin 'http: // localhost: 9200/index/_mapping/type' olarak nasıl değiştirildiği ile ilgili sonraki sürümler için. –

İlgili konular