Найти 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 оператор. Вот как это использовать.

  1. Построить текстовый индекс по нужным для поиска полям. Примечание. Для 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"});
    
  2. Запросите коллекцию с помощью оператора $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 поле.

Другие вопросы по тегам