2014-01-09 3 views
23

Da es nicht möglich ist, "blueberry" durch das Wort "blue" mit Hilfe einer Mongodb-Volltextsuche zu finden, möchte ich meinen Nutzern helfen, das Wort "blau" zu vervollständigen "Blaubeere". Um dies zu tun, ist es möglich, alle Wörter in einem Mongodb Volltextindex abzufragen -> dass ich die Wörter als Vorschläge verwenden kann, d. H. Für typeahead.js?MongoDB Volltextsuche + Workaround für Teilwortmatch

+0

Ich glaube nicht, dass das noch da ist, Sie könnten in der Lage sein, Abfragebedingungen zu verwenden, aber ich glaube, sie sind nicht bewertet: http://docs.mongodb.org/manual/reference/command/text/#search -with-additional-query-conditions – Sammaye

+0

Wer sagt, dass Partial Matching von Strings in MongoDB nicht möglich ist? http://stackoverflow.com/questions/3305561/how-to-query-mongodb-with-like –

+5

@DenizZoeteman Ich bin mir nicht sicher, ob Sie die Frage verstehen, dies ist über FTS nicht allgemeine Abfrage – Sammaye

Antwort

12

Language stemming in der Textsuche verwendet einen Algorithmus, um Wörter aus einer gemeinsamen Basis zu beziehen (zB. "Running" sollte "run" entsprechen). Dies unterscheidet sich von der Präfix-Übereinstimmung (z. B. "Blau", die "Blaubeere" entspricht), die Sie für eine Autovervollständigungsfunktion implementieren möchten.

Um am effektivsten nutzen typeahead.js mit MongoDB Textsuche würde ich auf der prefetch Unterstützung in typeahead vorschlagen Fokussierung:

  • erstellen keywords Sammlung, die die gemeinsamen Worte hat (vielleicht mit Zählung Nutzungshäufigkeit), die in Ihrem Sammlung. Sie können diese Sammlung in der Sammlung, in der Sie den Textsuchindex haben, unter running a Map/Reduce anlegen und die Wortliste mit einem periodischen Incremental Map/Reduce aktualisieren, wenn neue Dokumente hinzugefügt werden.

  • Lassen Sie Ihre Anwendung ein JSON-Dokument aus der keywords Sammlung mit den eindeutigen Schlüsselwörtern generieren (vielleicht beschränkt auf "populäre" Schlüsselwörter basierend auf der Worthäufigkeit, um die Liste überschaubar/relevant zu halten).

Sie können dann die erzeugten Schlüsselwörter JSON für die automatische Vervollständigung Client-Seite mit prefetch Funktion typeahead des verwenden:

$('.mysearch .typeahead').typeahead({ 
    name: 'mysearch', 
    prefetch: '/data/keywords.json' 
}); 

typeahead.js werden die prefetch JSON-Daten in localstorage für die clientseitige Suche zwischenzuspeichern. Wenn das Suchformular gesendet wird, kann Ihre Anwendung die serverseitige MongoDB text search verwenden, um die vollständigen Ergebnisse in Relevanzreihenfolge zurückzugeben.

+0

das ist mehr Mühe, die ich wollte nur eine nette Idee zu haben! thx – KIC

1

Sie können nicht alle Wörter im Index abfragen, aber Sie können natürlich die Felder des Originaldokuments abfragen. Die Wörter im Suchindex sind auch nicht immer die vollständigen Wörter, sind aber trotzdem stammend. So würden Sie wahrscheinlich nicht "Blaubeere" im Index finden, sondern nur "Blueberri".

1

Ich weiß nicht, ob dies für einige neue Leute, die mit diesem Problem konfrontiert sind, nützlich sein könnte.

Abhängig von der Größe Ihrer Sammlung und davon, wie viel RAM Ihnen zur Verfügung steht, können Sie mit $ regex suchen, indem Sie den richtigen Index erstellen. Z. B:

db.collection.find({query : {$regex: /querywords/}}).sort({'criteria': -1}).limit(limit) 

Sie würden einen Index müssen Sie wie folgt vor:

db.collection.ensureIndex({ "query": 1, "criteria" : -1 }) 

Das ist wirklich schnell sein könnte, wenn Sie über genügend Speicher.

Hoffe, das hilft.

+0

Wenn Sie nicht am Anfang des Textes suchen wollen, wird der Index trotzdem nicht verwendet. Index ist in diesem Fall nur eine Verschwendung von Ressourcen. – Skarllot

3

Eine einfache Problemumgehung, die ich gerade mache, besteht darin, den Text in einzelne Zeichen zu zerlegen, die als text-indexiertes Array gespeichert sind.

Dann, wenn Sie die $search Abfrage durchführen, brechen Sie einfach die Abfrage in Zeichen wieder auf.

Bitte beachten Sie, dass dies nur für kurze Strings gilt, die kürzer als 32 sind. Andernfalls wird der Indizierungsaufbau sehr lange dauern und die Performance wird beim Einfügen neuer Datensätze erheblich sinken.

+0

Grund für den Downvote? – Chen

1

Für diejenigen, die noch nicht mit der Implementierung einer Datenbank-Architektur begonnen haben und hier eine Lösung finden, gehen Sie zu Elasticsearch. Es ist eine json dokumentengesteuerte Datenbank, die strukturell dem mongodb ähnlich ist. Es hat "Edge-Ngram" -Analysator, der wirklich wirklich effizient und schnell ist, wenn Sie Sie meinten, für falsch buchstabierte Suchen. Sie können auch teilweise suchen.