48

我在数组“键”上有一个索引,我用它来为我的应用程序提供全文功能。

随着 2.4.3 的发布,我想使用“文本”索引类型。我在我的数组“键”上投保了“文本”索引类型,它似乎工作得非常快(比我的旧关键字全文方法快)。

问题是,我的应用程序假定字段是包容性的(AND)。默认情况下,文本搜索 ORs 我的参数。

有谁知道一种包含性地运行文本搜索的方法?

例如:

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

应该使用打印机和墨水返回结果,而不是使用打印机或墨水返回所有结果。

4

4 回答 4

81

试一试:

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

另外,这是来自docs的引用:

如果搜索字符串包含短语,则搜索将与搜索字符串中的任何其他词进行 AND;例如,搜索“\”twinkle twinkle\“little star”搜索“twinkle twinkle”和(“little”或“star”)。

希望有帮助。

于 2013-06-03T21:25:32.580 回答
6

您可以将每个单词用双引号括起来:

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

如果用户输入带引号的字符串,则有一个缺点,这将不起作用。您必须首先解析带引号的字符串。

于 2017-03-15T04:59:16.523 回答
1

正如@alecxe 之前指出的那样,要对文本索引列进行 AND 搜索,您需要对每个搜索词进行双引号。以下是满足您要求的快速单线。

db.supplies.runCommand("text", {search: "printer ink".split(" ").map(str => "\""+str+"\"").join(' ')})
于 2018-12-04T09:24:42.313 回答
-1

这是我使用节点中的子词进行搜索的一个简单函数。希望它可以帮助某人

假设用户搜索,pri nks因此它应该满足打印机和墨水,但 $text 搜索不允许这样做,所以这是我的简单功能:

    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)
于 2018-06-05T06:36:26.157 回答