【问题标题】:How can we treat groups of digits as strings in mongodb fulltext searches?我们如何在 mongodb 全文搜索中将数字组视为字符串?
【发布时间】:2015-03-26 12:00:18
【问题描述】:

在某个 ID 字段中,我们正在对文档进行索引,如下所示: 1234 45676

我们希望能够对两组数字中的每一组进行全文搜索,就像它们是字符串一样。我在引号中转义了数字组,mongo 文档说这将确保搜索整个字符串。

例如,如果索引字段中包含单词“blue”,则只会搜索单词“blue”。在“b”上搜索不会产生命中。 (我们暂时使用非词干搜索)。

但这不是数字组的结果。即使我们用引号 ("45676") 转义我们的数字组,数字组也会受到通配符搜索。在我们的示例中,搜索“4”将命中“45676”。

我们如何确保“45676”被视为只有在搜索“45676”时才会产生命中的字符串?

欢迎所有建议或观点!提前致谢。

【问题讨论】:

    标签: string mongodb full-text-search metacharacters


    【解决方案1】:

    将一组数字作为唯一的单个词进行搜索有两种解决方案。

    1) 使用 $text 操作符和文本索引

    2) 使用 $regexp 运算符或正则表达式。

    设置:

    db = connect("test"); // same as `use test;`
    db.a.drop();
    db.a.insert([
        { _id: 1, txt : "Log 1: Page 23 1234 45676" },
        { _id: 2, txt : "Log 2: Page 45 0000 00000" },
        { _id: 3, txt : "Log 3: Page 59 1337 11111" }
    ]);
    

    1。使用 $text 运算符的示例

    索引可搜索字段

    db.a.ensureIndex({ txt : "text" });
    

    使用 $text 运算符查询

    db.a.find({ $text : { $search : "45" } });
    

    输出

    { _id: 2, txt : "Log 2: Page 45 0000 00000" }
    

    请注意,输出不会返回 _id 为 1 的文档,即使它包含 45676

    2。使用正则表达式的示例

    对于正则表达式,您需要将数字包装在单词边界\b 中,以避免它们在字符串中匹配。

    示例: 正在搜索4,没有单词边界。

    /4/.test("4") == true
    /4/.test("1234") == true
    

    搜索带有单词边界的4

    /\b4\b/.test("4") == true
    /\b4\b/.test("1234") == false
    

    使用正则表达式搜索 45

    db.a.find({ txt : /\b45\b/ });
    

    输出

    { _id: 2, txt : "Log 2: Page 45 0000 00000" }
    

    您可以使用以下函数从用户输入中形成正则表达式。

    function escapeRegExp(str) {
      return String(str).replace(/[[\]/{}()*+?.\^$|-]/g, "\\$&");
    }
    function wordToRegExp( query ){
      return new RegExp( "\\b" + escapeRegExp( query ) + "\\b" );
    }
    var queryForWord = wordToRegExp( 45 );
    // queryForWord would be sent from your server side, not created in mongo shell.
    
    db.a.find({ txt : queryForWord });
    

    更多信息:

    【讨论】:

    • 谢谢——我现在更接近于理解这个问题了。它与数字无关。问题是我们的索引字段包含超过 1 个单词,例如“My Wonderful Product”。只要该字段包含单个单词或字符组,例如“MyWonderfulProduct”,那么一切都很好——例如“Wond”的查询词不会产生命中。但是在我们的字段设置为“My Wonderful Product”的情况下,每个词都是通配符:“Wond”的查询词会产生命中。
    • @BenWeaver 看看函数 wordToRegExp 是否有助于解决您的问题。
    • 对——我现在正在检查 wordToRegExp,并将在我们的 clojure 代码中重现它。谢谢!
    猜你喜欢
    • 2015-06-06
    • 2011-02-22
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2020-04-12
    相关资源
    最近更新 更多