Beste Möglichkeit, eine Volltextsuche in MongoDB und Mongoose durchzuführen

75

Ich suche seit Tagen bei Google und habe viele Dinge ausprobiert, kann aber immer noch keine gute Volltextsuche für meine Benutzersammlung durchführen.

Ich habe ElasticSearch ausprobiert, war aber ziemlich unmöglich abzufragen und zu paginieren ...

Ich habe viele Plugins für Mongoose ausprobiert, wie ElMongo, Mungo-Volltext, Mongoosastic usw. Alle sind wirklich schlecht dokumentiert und ich weiß nicht, wie man eine gute Volltextsuche durchführt.

Meine Sammlung ist also eine normale Sammlung:

user = {
  name: String,
  email: String,
  profile: {
    something: String,
    somethingElse: String
  }
}

Ich habe eine Sucheingabe auf einer Seite mit einer einfachen POST, wenn ich hello worldtippe, muss ich in den gesamten Sammlungsfeldern die passenden Wörter meiner Suchabfrage suchen und die Ergebnisse erhalten.

Es wird auch sehr schön sein, Optionen zu haben, um mit einer Paginierung wie 10 Elementen pro Seite oder so etwas umzugehen ...

Was ist die beste Lösung, um dies zu erreichen? Ich verwende MongoDB 2.6. * Mit Mongoose, NodeJS und ExpressJS.

Vielen Dank.

Ayeye Brazo
quelle

Antworten:

190

Sie können einen hinzufügen Textindex zu Ihrem Mungo - Schema - Definition , die Sie verwenden können , um die$text Operator in Ihren findAbfragen alle Felder im Textindex enthalten zu suchen.

So erstellen Sie einen Index zur Unterstützung der Textsuche für: nameund profile.something:

var schema = new Schema({
  name: String,
  email: String,
  profile: {
    something: String,
    somethingElse: String
  }
});
schema.index({name: 'text', 'profile.something': 'text'});

Wenn Sie alle Zeichenfolgenfelder in den Index aufnehmen möchten, verwenden Sie den '$**'Platzhalter:

schema.index({'$**': 'text'});

Auf diese Weise können Sie eine Suchabfrage für ausgelagerten Text wie folgt ausführen:

MyModel.find({$text: {$search: searchString}})
       .skip(20)
       .limit(10)
       .exec(function(err, docs) { ... });

Weitere Informationen finden Sie in der vollständigen Dokumentation zu MongoDB-Textindizes .

JohnnyHK
quelle
1
Danke für deine Antwort. Verringert dies nicht die MongoDB-Leistung? Noch eine Frage bitte: Kann ich auch die zu indizierenden Felder auswählen?
Ayeye Brazo
4
@AyeyeBrazo Ich habe den Anser aktualisiert, um zu zeigen, wie die zu indizierenden Felder ausgewählt werden. Das Hinzufügen eines Index erhöht den Overhead beim Einfügen und Aktualisieren sowie die Speicheranforderungen, sodass dies immer berücksichtigt werden muss.
JohnnyHK
3
Nach langer Suche ist Ihre Antwort König!
Holger D. Schauf
2
Gibt es die Möglichkeit, "wordA AND wordB" zu suchen? Und einen Teil der Wörter suchen?
Pumych
2
@Pumych überprüfen docs.mongodb.com/manual/reference/operator/query/text/… für Groß- und Kleinschreibung suchen
Prasanth Jaya
-33

Für Suchanfragen können Sie das Elasticsearch-Plugin verwenden. In Elasticsearch können Sie Ihre eigene benutzerdefinierte Suchabfrage erstellen, um einen bestimmten Text und eine bestimmte Zeichenfolge mit der angegebenen Zeitdauer in Echtzeit zu suchen.

Zuvor müssen Sie jedoch die Indizierung Ihrer in MongoDB befindlichen JSON-Dokumente vornehmen. Sie müssen MongoDB mit dem Elasticsearch-Server verbinden. Wenn Sie dann die River-Funktionalität von Elasticsearch verwenden, müssen Sie die Indizierung Ihrer Daten im Elasticsearch-Server vornehmen. Dann können nur Sie Ihre benutzerdefinierte Suchabfrage durchführen.

Shailendra Pathak
quelle