【问题标题】:MongoDB: multi-lingual (accent insensitive), case insensitive search, with partial words?MongoDB:多语言(不区分重音),不区分大小写的搜索,带有部分单词?
【发布时间】:2020-11-18 12:02:45
【问题描述】:

对于我们正在开发的应用程序,我们需要允许我们的搜索支持重音、不区分大小写和搜索部分单词。例如,给定我们集合中的产品名称“La Niña”,以下搜索应该会返回该条目:

  • 拉尼娜现象
  • 妮娜
  • 妮娜
  • 拉宁

目前我已经尝试了两种方法,根据测试和一些研究,每种方法都有明显的局限性:

  • Regex

    • 支持不区分大小写和部分搜索
    • 不支持重音,例如 niña != nina
  • Text Search

    • 支持不区分大小写、重音和部分短语
    • 不支持部分词

我们使用的正则表达式搜索示例:

function escapeRegExp(text) {
  return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

const escapedStr = this.escapeRegExp(searchTerm);
await Product.find({ name: new RegExp(`${escapedStr}`, 'i') });

我们使用的示例文本搜索:

// On the schema
storeSchema.index({ name: 'text' });

// Searching:
await Product.find($text: { $search: searchTerm })
  .collation({locale: 'en', strength: 1});

顺便说一句,我们已将相关架构设置为使用排序强度级别 1。

如果 MongoDB 不提供解决方案,我正在考虑的一些方法:

  • 阴影名称字段(不确定正确的术语?),已删除重音符号
  • 独立的全文搜索引擎

有人可以帮忙吗?

注意,我们使用的是 mongoose 5.9.5,节点 12.16.2 和 mongodb 4.3.8 在 mongo 云中运行。

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    我相信Text Search 是您所需要的。文本搜索还有两个其他功能可以满足您在问题中描述的部分单词匹配的要求。

    • 停用词:给定语言选项,MongoDB 文本搜索能够识别不应影响搜索结果的词。这些词的使用频率使得它们几乎出现在每个句子中,例如,在英语中,“the”、“a”、“of”之类的词都是停用词。在实际搜索发生之前,这些词会从搜索短语中删除。

    • 词干:给定一个语言选项,MongoDB 文本搜索能够识别单词的根版本,例如,在英语中,“identifying”的词干版本将是“identify”,因此它们都将匹配文本搜索”。

    通过 Google 翻译,我发现您提供的“拉尼娜”示例是西班牙语。

    如果我将以下内容插入到示例产品集合中:

    db.products.insertMany([
      { "term" : "La Niña" },
      { "term" : "niña" },
      { "term" : "nina" },
      { "term" : "nin" },
      { "term" : "La nin" },
    ]) 
    

    通过在我的测试搜索查询中指定“西班牙语”的语言选项:

    db.products.find({ $text: { $search: "La Niña", $language: "spanish" } })
    

    MongoDB 将有效地将其与之前插入的所有产品相匹配。您可以获取 MongoDB here 支持的语言选项列表。

    不过,我不能 100% 确定重音匹配的工作原理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-22
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多