Найкращий спосіб виконати повнотекстовий пошук у MongoDB та Mongoose


76

Я шукаю в Google кілька днів, і я спробував багато речей, але все ще не можу виконати хороший повнотекстовий пошук у своїй колекції користувачів.

Я спробував ElasticSearch, але зробити запити та перенести сторінки було майже неможливо ...

Я спробував багато плагінів для Mongoose, таких як ElMongo, mongoose-full-text, Mongoosastic тощо ... всі насправді погано задокументовані, і я не знаю, як виконати хороший повнотекстовий пошук.

Отже, моя колекція - це звичайна колекція:

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

У мене є пошуковий ввід на сторінці з простим POST, якщо я набираю hello worldте, що мені потрібно, це шукати у всіх полях колекції відповідні слова мого пошукового запиту та отримати результати.

Буде дуже приємно також мати варіанти обробки пагінації, як 10 елементів на сторінку або щось інше ...

Яке найкраще рішення для досягнення цього? Я використовую MongoDB 2.6. * З Mongoose, NodeJS та ExpressJS.

Дякую.

Відповіді:


195

Ви можете додати текстовий індекс до визначення схеми Mongoose, що дозволяє використовувати $textоператор у ваших findзапитах для пошуку всіх полів, включених до текстового індексу.

Щоб створити індекс, що підтримує пошук тексту, скажімо, nameта profile.something:

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

Або якщо ви хочете включити в рядок усі поля рядків, використовуйте '$**'підстановочний знак:

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

Це дозволить вам виконати пошуковий запит з текстовим пошуком, наприклад:

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

Щоб отримати докладнішу інформацію, прочитайте повну документацію щодо текстових індексів MongoDB .


1
Дякую за вашу відповідь. Чи не знижує продуктивність MongoDB це? Ще одне запитання: чи можу я також вибрати поля для індексації?
Ayeye Brazo,

4
@AyeyeBrazo Я оновив anser, щоб показати, як вибрати поля для індексації. Додавання будь-якого індексу додає накладні витрати під час вставки та оновлення, а також додані вимоги до сховища, так що це завжди слід враховувати.
JohnnyHK

4
після довгих пошуків, ваша відповідь король!
Holger D. Schauf

2
Чи є можливість зробити пошук за "wordA І wordB"? А шукати частину слів?
Пумич

2
@Pumych перевірити docs.mongodb.com/manual/reference/operator/query/text/… для пошуку з урахуванням регістру
Прасант Джая,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.