2015-06-19 14 views
8

Przechowuję różne rodzaje dokumentów w jednym indeksie ze ściśle zdefiniowanym wcześniej mapowaniem. Wszystkie mają trochę pola (powiedzmy "ciało"), ale chciałbym, aby były analizowane nieco inaczej po zindeksowaniu (na przykład, aby używać różnych filtrów tokenów dla konkretnych dokumentów) i traktować w ten sam sposób podczas wyszukiwania. O ile mi wiadomo, analizatorów nie można określić dla każdego dokumentu.Elastyczne wyszukiwanie wielu analizatorów dla pojedynczego pola

Co ja również rozważyć użycie:

  1. pól obiektu z różnie analizowane podpola dla rodzajów dokumentów, więc każdy dokument ma tylko jeden wypełniony podpole (jak „body.mail”, „body.html”) . Problem polega na tym, że nie mogłem przeszukiwać całego pola "ciało", które przejrzałoby wszystkie jego subpola (aby nie złamać istniejącej aplikacji).
  2. Nowa reinkarnacja wielu pól (aby mieć pole "ciało" z generycznym analizatorem i regularnie analizowane "mail", "html" itp. W środku). Jednak nie jestem pewien, czy możliwe jest ich bezpośrednie użycie podczas indeksowania i pośrednio podczas wyszukiwania (np., Aby zapisać obiekt za pomocą {"mail":"smth"}, aby użyć określonego analizatora indeksów, następnie przeszukać przez "query":{"body":"smth"}, aby użyć generycznego analizatora wyszukiwania).
  3. Aby oddzielić "treść" na kilka pól z różnymi mapowaniami, usuń je z _all i ustaw copy_to na jedno pole body. Nie jestem pewien, ale doda znaczny narzut z powodu kopiowania.
+2

Dlaczego nie indeksować różnych pól, takich jak "mail", "html" itp., Mieć dla każdego inny analizator i użyć kwerendy z wieloma dopasowaniami do wyszukiwania we wszystkich tych polach? https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html – Ita

+0

Moim zdaniem te dwa wymagania nie są możliwe razem: "wyszukiwanie w całości pole "body", które będzie przeglądać wszystkie swoje subpola (** aby nie złamać istniejącej aplikacji **) 'i' przeanalizowane trochę inaczej, gdy zostaną zindeksowane i traktowane w ten sam sposób podczas wyszukiwania. Coś musi dać. –

+0

@Ita starsze powody. Istnieje już wiele zapytań na tym polu, więc trudno będzie zastąpić każdy z nich wieloma meczami. – Yuuri

Odpowiedz

13

Jak już wspomniałem w komentarzach, to, czego chcesz, nie jest możliwe. Twoje zdanie, w jednym zdaniu, brzmi: czy te same dane zostały przeanalizowane na wiele sposobów, ale przeszukano je jako pojedyncze pole, ponieważ mogłoby to zepsuć istniejącą aplikację.

   -- body.html   
      -- body.email 
body field ---- body.content  --- all searched as "body" 
      ... 
      -- body.destination 
      -- body.whatever 
  • Twoja pierwsza opcja jest multi-pola który ma dokładnie ten cel na uwadze: mają te same dane analizowano wiele sposobów. Problem polega na tym, że nie można wyszukać "body" i oczekiwać, że ES wyszuka body.html, body.email ... Nawet jeśli byłoby to możliwe, należy przeszukać za pomocą różnych analizatorów. Ponownie, nie jest to możliwe. Ta opcja wymaga, aby zmienić aplikację i wyszukać każde pole w postaci multi_match lub .

  • Twoja druga opcja - reincarnation of multi-fields - znowu nie działa, ponieważ nie może odnosić się do body i ES, w tle, aby dopasować mail, content itp

  • Trzecia opcja - wykorzystanie copy_to - nie będzie działa, ponieważ kopiowanie do innego pola "X" oznacza indeksowanie kopiowanych danych. zostanie przeanalizowane przy użyciu analizatora, a to z kolei spowoduje złamanie wymogu analizy tych samych danych w różny sposób.

  • Może być jedna czwarta opcja - "path": "just_name" from multi_fields - która na pierwszy rzut oka powinna zadziałać. Oznacza to, że możesz mieć 3 multi-pola (e-mail, zawartość, html), które wszystkie trzy mają sub-pole body. Posiadanie "path": "just_name" pozwala na wyszukiwanie tylko dla body, nawet jeśli body jest podpolem wielu innych pól. Nie jest to jednak możliwe, ponieważ ten typ wielu pól nie przyjmuje różnych analizatorów dla tego samego body.

Tak czy inaczej, trzeba zmienić coś w swoim wymagań, ponieważ nie będą oni pracować tak, jak chcesz.


To zostało powiedziane, jestem ciekaw co zapytań używasz w swojej aplikacji. Byłaby to prosta zmiana (tak, musisz zmienić swoją aplikację) z pola body zapytanie na zapytanie body.* w multi_match.

Mam dla ciebie jeszcze jedno rozwiązanie: twórz wiele indeksów, jeden indeks dla każdego analizatora twojego body. Na przykład, dla mail, content i html zdefiniować trzy indeksy:

PUT /multi_fields1 
{ 
    "mappings": { 
    "test": { 
     "properties": { 
     "body": { 
      "type": "string", 
      "index_analyzer": "whitespace", 
      "search_analyzer": "standard" 
     } 
     } 
    } 
    } 
} 
PUT /multi_fields2 
{ 
    "mappings": { 
    "test": { 
     "properties": { 
     "body": { 
      "type": "string", 
      "index_analyzer": "standard", 
      "search_analyzer": "standard" 
     } 
     } 
    } 
    } 
} 
PUT /multi_fields3 
{ 
    "mappings": { 
    "test": { 
     "properties": { 
     "body": { 
      "type": "string", 
      "index_analyzer": "keyword", 
      "search_analyzer": "standard" 
     } 
     } 
    } 
    } 
} 

Widać, że wszyscy mają taką samą type i taką samą nazwę pola - body - ale różne index_analyzer s. Następnie należy zdefiniować alias:

POST _aliases 
{ 
    "actions": [ 
    {"add": { 
     "index": "multi_fields1", 
     "alias": "multi"}}, 
    {"add": { 
     "index": "multi_fields2", 
     "alias": "multi"}}, 
    {"add": { 
     "index": "multi_fields3", 
     "alias": "multi"}} 
    ] 
} 

Nazwij swój alias tak jak bieżący indeks. Aplikacja nie musi się zmieniać, będzie używać tej samej nazwy do wyszukiwania indeksu, ale ta nazwa nie wskaże indeksu, ale do aliasu, który z kolei odnosi się do wielu wskaźników. Co musi się zmienić sposób indeksowania dokumentów, bo html dokumenty musi iść w multi_fields1 wskaźnika na przykład dokument email musi być indeks multi_fields2 indeksu itp

Niezależnie rozwiązanie można znaleźć/wybrać Twoje wymagania potrzebne zmienić, ponieważ sposób, w jaki tego chcesz, nie jest możliwy.

3

Myślę, że można używać wielu pól. W przypadku wielu pól można zdefiniować analizatory (oba indeksujące: &) dla każdego pola podrzędnego, a wyszukiwanie w odpowiednich polach będzie oparte na wymaganiach aplikacji. Ogólnie rzecz biorąc, analizator indeksów może różnić się w zależności od pola, tak samo dla analizatora wyszukiwania.

 
{ 
    "your_type" : { 
    "properties":{ 
     "body" : { 
      "type" : "string", 
      "index" : "analyzed", 
      "index_analyzer" : "index_body_analyzer", 
      "search_analyzer" : "search_body_analyzer", 
      "fields" : { 
       "mail" : { 
        "type" : "string", 
        "index" : "analyzed", 
        "index_analyzer" : "index_bodymail_analyzer", 
        "search_analyzer" : "search_bodymail_analyzer" 
       }, 
       "html": { 
        "type" : "string",    
        "index" : "analyzed", 
        "index_analyzer" : "index_bodyhtml_analyzer", 
        "search_analyzer" : "search_bodyhtml_analyzer" 
       } 
      } 
     } 
    } 
}
+0

Czy możliwe jest indeksowanie danych "do" pola 'html' (z jego index_analyzer), a następnie wyszukiwanie w polu' body' (z jego parametrem search_analyzer)? To drugie ma kluczowe znaczenie dla kompatybilności wstecznej. – Yuuri

+0

Masz na myśli dane różnic indeksu w 'html'? lub te same dane z 'body', tylko różnica w index_analyzer?Jeśli te same dane, ES już zrobiła to za Ciebie poprzez definicje wielu pól. Możesz podać przykładowe dane na pytanie, aby wyjaśnić. –

+0

Mam na myśli indeksowanie obiektów takich jak '[{" id ": 1," html ":" ... "}, {" id ": 2," mail ":" ... "}]' (lub '" body.html ":" ... "', itp.), aby użyć różnych analizatorów indeksów, ale aby wyszukiwać jak '" zapytanie ":" body: smth "' aby użyć pojedynczego analizatora wyszukiwania. Obecnie eksperymentuję z odwzorowaniami, ale nadal nie mogę wykonać mojego starego interfejsu wyszukiwania (który korzysta z funkcji 'body' w zapytaniach). – Yuuri

Powiązane problemy