2013-07-08 6 views
7

Próbuję określić najlepszy sposób indeksowania dokumentu w trybie elastycznego wyszukiwania. Mam dokument, Doc, który ma kilka pól:Jak uniknąć przeszukiwania obiektów krzyżowych za pomocą typów zagnieżdżonych w wyszukiwaniu elastycznym

Doc 
    created_at 
    updated_at 
    field_a 
    field_b 

Ale Doc będzie również mieć pola specyficzne dla poszczególnych użytkowników. Na przykład field_x będzie miał wartość "A" dla użytkownika 1, a field_x będzie mieć wartość "B" dla użytkownika 2. Dla każdego dokumentu będzie bardzo ograniczona liczba użytkowników (zwykle 2, do ~ 10). Gdy użytkownik wyszukuje na field_x, musi wyszukać wartość, która do nich należy. Badałem typy zagnieżdżone w ES.

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

Gdy użytkownik 1 wyszukuje wartość field_x dla wartości "A", dokument ten powinien spowodować trafienie. Jednak nie powinno to być, gdy użytkownik 1 wyszukuje wartość "B".

Jednak according to the docs:

Jednym z problemów podczas indeksowania wewnętrznych obiektów, które pojawiają się kilka razy w dokumencie, że „krzyż obiekt” szukaj mecz nastąpi

Czy istnieje sposób Aby uniknąć tego zachowania z typami zagnieżdżonymi, czy powinienem zbadać inny typ?

Dodatkowe informacje dotyczące wykonywania takich zapytań byłyby bardzo cenne. Po przeczytaniu dokumentów stwierdzono, że zagnieżdżone zapytania nie różnią się zbytnio pod względem wydajności w odniesieniu do zwykłych zapytań. Jeśli ktokolwiek ma prawdziwe doświadczenie, bardzo chciałbym to usłyszeć.

Odpowiedz

5

Zagnieżdżony typ jest tym, czego szukasz i nie martw się zbytnio wydajnością.

Przed indeksowania dokumentów, trzeba ustawić mapowanie dla dokumentów:

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* 
        } 
       } 
      } 
     } 
    } 
}' 

* UWAGA: Jeśli pole naprawdę zawiera tylko pojedynczej litery takie jak „A” i „B”, don” t chcesz analizować pole, w przeciwnym razie funkcja elasticsearch usunie te "słowa" w liczbie pojedynczej. Jeśli był to tylko twój przykład, w swoich prawdziwych dokumentach szukasz odpowiednich słów, usuń tę linię i pozwól, aby analiza elastyczna przeszukała to pole.

Następnie indeks dokumenty:

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" 
    }] 
}' 

i uruchomić zapytanie:

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" 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
}'; 

To spowoduje

{"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" 
    }] 
}}]}} 

Jednak zapytań

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" 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
}'; 

nie zwróci żadnych wyników

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

To wielki odpowiedź. Dokładnie to, czego szukałem. Dziękuję za dokładność. – Brad

+0

to stara odpowiedź, [patrz dokumentacja] (https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-put-mapping.html) dla późniejszych wersji zmieniających adres URL mapowania na 'http: // localhost: 9200/index/_mapping/type'. –

Powiązane problemy