2017-06-12 2 views
0

Ich werde versuchen, meinen Fall auf das Notwendige zu reduzieren: Ich baue eine Webapp (mit Spring) mit einer Suchschnittstelle, die Sie einen Korpus von kommentierten/markierten Texten durchsuchen können. In meiner Datenbank (MongoDB) repräsentiert ein Dokument eine Seite einer Buchsammlung (insgesamt ~ 8000 Seiten).Wie indexieren Dokumente mit verschachtelten Eigenschaften mit Lucene?

Hier ein Beispiel für die Dokumentstruktur in JSON ist (. I der Kürze halber viele Metadaten entfernt auch, und dies ist wichtig, die „Token“ -array enthält auf 700 Objekte in den meisten Fällen auf.):

{ 
    "_id" : ObjectId("5622c29eef86d3c2f23fd62c"), 
    "scanId" : "592ea208b6d108ee5ae63f79", 
    "volume" : "Volume I", 
    "chapters" : [ 
     "Some Chapter Name" 
    ], 
    "languages" : [ 
     "English", 
     "German" 
    ], 
    "tokens" : [ 
     { 
      "form" : "The", 
      "index" : 0, 
      "tags" : [ 
       "ART" 
      ] 
     }, 
     { 
      "form" : "house", 
      "index" : 1, 
      "tags" : [ 
       "NN", 
       "NN_P" 
      ] 
     }, 
     { 
      "form" : "is", 
      "index" : 2, 
      "tags" : [ 
       "V", 
       "CONJ_C" 
      ] 
     } 
    ] 
} 

So sehen Sie, ich habe hier keinen Klartext. Ich möchte jetzt einen Index mit Lucene erstellen, um diese DB schnell zu durchsuchen. Das Problem ist, dass ich in der Lage sein möchte, bestimmte Wörter, ihre Tags und den Kontext um sie zu suchen. Wie "gib mir alle Dokumente, die das Wort 'House' enthalten, mit 'NN' gefolgt von einem Wort, das mit 'V' markiert ist." Ich konnte keine Möglichkeit finden, diese Unterstrukturen mit der nativen Lucene-Funktionalität zu indizieren.

Was ich versuchte, um wenigstens nach Wörtern und ihren Tags suchen zu können, ist folgendes: In meinem Lucene-Index repräsentiert ein Dokument nicht eine ganze Seite, sondern nur ein Wort/Token mit seinen Tags. So ein Index Dokument sieht wie folgt aus (in JSON-Syntax zur besseren Lesbarkeit):

{ 
    "token" : "house", 
    "tag" : "NN", 
    "tag" : "NN_P", 
    "index" : 1, 
    "pageId" : "5622c29eef86d3c2f23fd62c" 
} 

... Ja, Lucene erlaubt es mir, ein Feld mehrfach zu verwenden. So kann ich nun nach einem Wort und dessen Tags suchen und über die ID einen Verweis auf das Seitenobjekt in meiner DB bekommen. Aber das ist aus zwei Gründen ziemlich hässlich: Ich habe jetzt zwei völlig verschiedene Dokumentdarstellungen (DB und Lucene-Index) und um eine komplexe Abfrage wie die oben erwähnte zu verarbeiten, müsste ich nach dem Wort und seinem Tag suchen und dann weiter Überprüfen Sie den Kontext der Treffer in den abgerufenen Dokumenten manuell.

Meine Frage ist also: Gibt es eine Möglichkeit, Dokumente in Lucene zu indizieren, die Felder/Eigenschaften enthalten, deren Werte verschachtelte Objekte sind, die wiederum bestimmte Eigenschaften haben?

+0

Muss dies reines Lucene sein oder könnten Sie elasticsearch verwenden? – stripybadger

+0

@stripybadger Nun, ich würde es gerne vermeiden, meine App mit mehr und mehr komplexen Komponenten in die Luft zu sprengen, wenn es möglich wäre - aber wenn du sagst, dass es Dinge möglich machen würde, würde ich natürlich bereit sein, darüber nachzudenken. – mumpitz

Antwort

0

Gibt es eine Möglichkeit, Dokumente in Lucene zu indizieren, die Felder/Eigenschaften enthalten, deren Werte verschachtelte Objekte sind, die wiederum bestimmte Eigenschaften haben?

Mit Elasticsearch können Sie dies sicher tun. Ich denke, es ist möglich, alles in reinem Lucene zu machen, aber es könnte etwas Anstrengung sein.

Grundsätzlich müssen Sie die ‚verschachtelte‘ Abfrage verwenden: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

PUT /my_index 
{ 
    "mappings": { 
     "type1" : { 
      "properties" : { 
       "tokens" : { 
        "type" : "nested" 
       } 
      } 
     } 
    } 
} 

Dies teilt ES indiziert den Inhalt dieses Feldes als eine Liste von separaten Dokumenten, so dass Sie sie einzeln abzufragen der Verwendung von ' verschachtelte 'Query:

+0

Es war lange her, sorry. Ich habe diese Antwort jetzt akzeptiert, weil das, was sie sagt, wahr ist: Lucene unterstützt das Verschachteln von Dokumenten nicht ohne weiteres. Es * kann * getan werden, indem man die Dokumente abflacht, aber es ist ein wenig hacky, es selbst zu machen. ** elasticsearch ** und ** solr ** machen das automatisch für Sie, aber das bedeutet einen gewissen Overhead für Ihre App, was nicht unbedingt das ist, was Sie wollen, wenn es nur eine kleine App ist. – mumpitz

Verwandte Themen