2015-06-19 17 views
8

Ich speichere verschiedene Arten von Dokumenten in einem einzigen Index mit strengen vordefinierten Mapping. Alle haben ein Feld (etwa "body"), aber ich möchte, dass sie bei der Indizierung etwas anders analysiert werden (zum Beispiel um verschiedene Token-Filter für bestimmte Dokumente zu verwenden) und auf dieselbe Weise behandelt werden, während sie gesucht werden. Soweit ich weiß, können Analysatoren nicht pro Dokument spezifiziert werden.Elasticsearch mehrere Analysatoren für ein einzelnes Feld

Was ich auch zu nutzen gilt:

  1. Objektfelder mit unterschiedlich Unterfelder für die Dokumentarten analysiert, so dass jedes Dokument hat nur einen gefüllten Teilfeld (wie: „body.mail“, „body.html“) . Das Problem ist, dass ich nicht das gesamte "Körper" -Feld durchsuchen konnte, das durch alle seine Unterfelder schauen würde (um die bestehende Anwendung nicht zu durchbrechen).
  2. Neue Reinkarnation von Multi-Feldern (um "Körper" Feld mit einem generischen Analysator zu haben und analysiert "Mail", "HTML", etc.). Ich bin mir nicht sicher, ob es möglich ist, sie direkt während der Indizierung und indirekt während der Suche zu verwenden (z. B. Objekt mit {"mail":"smth"} zu speichern, um einen spezifischen Indexanalysator zu verwenden, dann Suche nach "query":{"body":"smth"}, um generischen Suchanalysator zu verwenden).
  3. Um "body" in mehrere Felder mit unterschiedlichen Zuordnungen zu trennen, entfernen Sie diese aus _all und setzen Sie auf ein einzelnes body Feld. Ich bin mir nicht sicher, aber es wird einen erheblichen Index-Overhead aufgrund des Kopierens hinzufügen.
+2

Warum indexieren Sie nicht verschiedene Felder wie "mail", "html" usw., haben jeweils einen anderen Analyzer und verwenden eine Multi-Match-Abfrage, um alle diese Felder zu suchen? https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html – Ita

+0

Meiner Meinung nach sind diese beiden Anforderungen nicht zusammen möglich: 'Suche im Großen und Ganzen "body" -Feld, das durch alle seine Unterfelder schauen würde (** um die existierende Anwendung nicht zu brechen **) 'und' leicht anders analysiert, wenn indexiert und auf die gleiche Weise behandelt wird, während gesucht wird '. Etwas muss geben. –

+0

@Ita Legacy Gründe. Es gibt bereits viele Suchanfragen zu diesem Feld, so dass es schwierig und anspruchsbasiert wäre, jedes mit mehreren Übereinstimmungen zu ersetzen. – Yuuri

Antwort

13

Wie ich in den Kommentaren erwähnt, was Sie wollen, ist nicht möglich. Ihre Anforderung in einem Satz lautet: Lassen Sie dieselben Daten auf verschiedene Arten analysieren, suchen Sie aber als einzelnes Feld, da dies die bestehende Anwendung durchbrechen würde.

   -- body.html   
      -- body.email 
body field ---- body.content  --- all searched as "body" 
      ... 
      -- body.destination 
      -- body.whatever 
  • Ihre erste Option ist Multi-Felder, die genau dieses Ziel vor Augen hat: haben die gleichen Daten mehrere Möglichkeiten analysiert. Das Problem ist, dass Sie nicht nach "body" suchen können und erwarten, dass ES body.html, body.email ... sucht. Auch wenn dies möglich wäre, möchten Sie mit verschiedenen Analysatoren gesucht werden. Nochmal nicht möglich. Diese Option erfordert, dass Sie die Anwendung ändern und nach jedem Feld in einer multi_match oder in einer query_string suchen.

  • Die zweite Möglichkeit - reincarnation of multi-fields - wieder nicht funktionieren, weil Sie nicht zu body und ES, im Hintergrund verweisen können, mail übereinstimmen, content usw.

  • dritte Option - copy_to mit - wird nicht arbeiten, weil das Kopieren in ein anderes Feld "X" bedeutet Indexierung der Daten kopiert wird analysiert mit X Analysator, und dies bricht Ihre Anforderung, die gleichen Daten unterschiedlich analysiert werden.

  • Es könnte eine vierte Option geben - "path": "just_name" from multi_fields - die auf den ersten Blick sollte es funktionieren. Das heißt, Sie können 3 Multi-Felder (E-Mail, Inhalt, HTML) haben, die alle drei ein body Unterfeld haben. Mit "path": "just_name" können Sie nur nach body suchen, auch wenn body ein Unterfeld mehrerer anderer Felder ist. Dies ist jedoch nicht möglich, da diese Art von Mehrfachfeldern keine anderen Analysatoren für denselben body akzeptiert.

So oder so, müssen Sie etwas in Ihren Anforderungen ändern, weil sie sie nicht so funktionieren Sie es wollen.


Diese wird gesagt, ich bin gespannt zu sehen, welche Anfragen sind Sie in Ihrer Anwendung verwenden. Es wäre eine einfache Änderung (ja, Sie müssen Ihre App ändern) von der Abfrage body Feld zur Abfrage body.* in einer multi_match.

Und ich habe eine andere Lösung für Sie: Erstellen Sie mehrere Indizes, einen Index für jeden Analysator Ihrer body. Zum Beispiel für mail, content und html Sie definieren drei Indizes:

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

Sie sehen, dass alle von ihnen type und den gleichen Feldnamen die gleiche haben - body - aber unterschiedliche index_analyzer s. Dann definieren Sie einen Alias:

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

Benennen Sie Ihren Alias ​​den gleichen wie Ihren aktuellen Index. Die Anwendung muss nicht geändert werden, sie verwendet denselben Namen für die Indexsuche aber Dieser Name verweist nicht auf einen Index, sondern auf einen Alias, der sich wiederum auf Ihre Mehrfachindizes bezieht. Was muss sich ändern, wie Sie Index ist die Dokumente, weil ein html Dokumente zum Beispiel in multi_fields1 Index gehen muss, muss ein email Dokument Index in multi_fields2 Index sein usw.

Was auch immer Sie Lösung finden/wählen, Ihre Anforderungen benötigen ändern, weil die Art, wie Sie es wollen, nicht möglich ist.

3

Ich denke, dass Sie Multi-Feld verwenden können. Mit dem Multi-Feld können Sie Analysatoren (beide Indizierung & Suche) für jede Unterfelder definieren, und die Suche auf entsprechenden Feldern basierend auf Anwendungen Anforderungen. Im Allgemeinen kann Index Analysator von Feld zu Feld unterscheiden, das gleiche für Suchanalysator.

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

Ist es möglich, Daten in "html" -Feld (mit seinem index_analyzer) zu indizieren, dann die Suche auf 'body'-Feld (mit seinem search_analyzer)? Letzteres ist entscheidend für die Rückwärtskompatibilität. – Yuuri

+0

Sie meinen Index Differenz Daten in 'html'? oder die gleichen Daten mit "Körper", nur Unterschied in index_analyzer?Wenn dieselben Daten vorhanden sind, hat es ES bereits für Sie durch Multi-Feld-Definitionen getan. Sie können Beispieldaten zu der Frage bereitstellen, um die Details zu verdeutlichen. –

+0

Ich meine Objekte zu indizieren wie '[{" id ": 1," html ":" ... "}, {" id ": 2," mail ":" ... "}]' (oder '" body.html ":" ... "usw.), um verschiedene Indexanalysatoren zu verwenden, aber wie" query ":" body: smth "' zu suchen, um den einzelnen Suchanalysator zu verwenden. Ich experimentiere gerade mit Mappings, kann aber immer noch nicht mein altes Suchinterface (das 'body' in Queries verwendet) arbeiten lassen. – Yuuri

Verwandte Themen