Подтвердить что ты не робот

Текстовый поиск MongoDB и несколько поисковых слов

У меня есть указатель на "ключи" массива, которые я использую для обеспечения полнотекстовых функциональных возможностей для моего приложения.

С выпуском 2.4.3 я бы хотел использовать индексный тип текста. Я застраховал "текстовый" тип индекса в "ключах" моего массива и, похоже, работает SUPER быстро (быстрее, чем мой старый текстовый метод).

Проблема заключается в том, что в моем приложении предполагается, что поля включены (AND). По умолчанию текстовые поисковые ORs мои параметры.

Кто-нибудь знает способ запуска текстового поиска включительно?

Например:

db.supplies.runCommand("text", {search:"printer ink"})

должен возвращать результаты как с принтером, так и с чернилами вместо всех результатов с помощью принтера или чернил.

4b9b3361

Ответ 1

Попробуйте:

db.supplies.runCommand("text", {search:"\"printer\" \"ink\""})

Кроме того, здесь цитата из docs:

Если строка поиска содержит фразы, поиск выполняет И с любые другие термины в строке поиска; например искать "\" мерцание twinkle\ "little star" ищет "мерцание мерцания" и ( "маленькое" или "Звезда" ).

Надеюсь, что это поможет.

Ответ 2

Вы можете обернуть каждое слово в двойные кавычки:

let keywords = ctx.params.query.split(/\s+/).map(kw => `"${kw}"`).join(' ');
match.$text = { $search: keywords, $caseSensitive: false };

Существует недостаток, если пользователь вводит строку с кавычками, это не сработает. Сначала вам придется разбирать строки с кавычками.

Ответ 3

Как ранее указывал @alecxe, чтобы выполнить поиск AND в столбце текстового индекса, вам нужно дважды указать каждое слово поиска. Ниже приведен быстрый однострочный вкладыш для вашего требования.

db.supplies.runCommand("text", {search: "printer ink".split(" ").map(str => "\""+str+"\"").join(' ')})

Ответ 4

Вот простая функция, которую я сделал для поиска с использованием подслов в узле. Надеюсь, это поможет кому-то

Предположим, что пользователь ищет pri nks поэтому он должен удовлетворять принтеру и чернилам, но текстовый поиск не позволяет этого, так вот моя простая функция:

    var makeTextFilter = (text) => {
    var wordSplited = text.split(/\s+/);
    /** Regex generation for words */
    var regToMatch = new RegExp(wordSplited.join("|"), 'gi');
    let filter = [];
    searchFieldArray.map((item,i) => {
        filter.push({}); 
        filter[i][item] = {
            $regex: regToMatch,
            $options: 'i'
        }
    })

    return filter;
  }

и используйте его в своем запросе как это

let query = {...query, $or: makeTextFilter(textInputFromUser)}
tableName.find(query, function (err, cargo_list)