Найти n слов внутри документа Mongodb
Я пытаюсь создать запрос, который находит коллекцию документов, соответствующих критериям, простую поисковую систему. Проблема в том, что ресурсы внутри коллекции выглядят так:
{
fristName: "foo",
lastName: "bar",
description: "mega foo",
},
{
fristName: "Lorem",
lastName: "Ipsum",
description: "mega Lorem bla bla",
},
Если пользователь хочет все активы, содержащие слово bar, я должен показать актив 1 примера, и это не проблема, но что, если он вводит foo mega?, в этом случае мне также нужно показать актив 1, потому что foo и mega присутствуют в активе 1 (оба), если он ищет только мега, выходные данные - актив 1 и 2, и если он ищет мега ipsum, результат - актив 2. Я понятия не имею, как написать этот запрос в mongoDb.
2 ответа
Mongodb 2.6+ имеет встроенную поддержку текстового поиска с использованием $text
оператор. Вот как это использовать.
Построить текстовый индекс по нужным для поиска полям. Примечание. Для MongoDB 2.6 в коллекции может быть только 1 текстовый индекс.
Создать текстовый указатель на одном поле
db.test.ensureIndex({ "field1" : "text" }, { name : "Field1TextIndex"});
Создать текстовый указатель на два поля
db.test.ensureIndex({ "field1" : "text", "field2" : "text" }, { name : "Field12TextIndex"});
Создать текстовый индекс для любого строкового поля
db.test.ensureIndex({ "$**" : "text" }, { name : "AllTextIndex"});
Запросите коллекцию с помощью оператора $text.
Вот формат для
$text
{ $text: { $search: <string of keywords>, $language: <string> } }
Пример кода
Настроить
use test;
var createPerson = function(f,l,d){
return { firstName : f, lastName: l, description : d};
};
db.test.remove({});
db.test.insert(createPerson("Ben", "Dover", "Real Estate Agent"));
db.test.insert(createPerson("James", "Bond", "secret agent, ben's friend"));
Создание текстового индекса для всех строковых полей в документе.
db.test.ensureIndex({ "$**" : "text" }, { name : "AllTextIndex"});
Запросить все поля для ключевых слов
В поисках ben
db.test.find({
$text : {
$search : "ben"
}
});
Выход
{ "_id" : "...", "firstName" : "James", "lastName" : "Bond", "description" : "secret agent, ben's friend" }
{ "_id" : "...", "firstName" : "Ben", "lastName" : "Dover", "description" : "Real Estate Agent" }
Поиск "Бен" вернул оба документа, так как один Ben
как firstName
а другой имел ben's
в description
поле.
Запрос для real friend
дает тот же результат.
db.test.find({
$text : {
$search : "real friend"
}
});
Больше информации здесь:
Возможное решение - поиск по ключевым словам. Я имею в виду, вы должны добавить keywords
поле для каждого объекта, например:
{
fristName: "foo",
lastName: "bar",
description: "mega foo",
keywords: ["foo", "bar", "mega"]
},
{
fristName: "Lorem",
lastName: "Ipsum",
description: "mega Lorem bla bla",
keywords: ["mega", "Lorem", "Ipsum", "bla"]
},
Вы должны разделить строку запроса на ключевые слова, например
"foo mega"
будет преобразован в
["foo", "mega"]
а затем вы можете искать объекты по keywords
поле.