【问题标题】:MongoDB query to find documents with variationsMongoDB查询以查找具有变化的文档
【发布时间】:2019-05-24 22:37:50
【问题描述】:

示例 MongoDB 文档:

{
  name: "something"
  product: "ABC-123"
}

问题是产品可能并不总是遵循相同的命名约定。可以是以下任何一种

"ABC-123"
"ABC123"
"ABC 123"

因此,如果我搜索“ABC-123”,我想要任何类似匹配的文档,而不管命名约定的变化。

【问题讨论】:

    标签: node.js regex mongodb mongodb-query regex-group


    【解决方案1】:

    编辑:您可以使用表达式^ABC(?:.*?)\\d+$ 在查询中简单地使用$regex,如下所示:

    示例 MongoDB 文档:

    db={
      "products": [
        {
          "name": "product A",
          "product": "ABC-123"
        },
        {
          "name": "product B",
          "product": "ABC123"
        },
        {
          "name": "product C",
          "product": "ABC-123"
        }
      ]
    }
    

    查询:

    db.products.find({
      "product": {
        "$regex": "^ABC(?:.*?)\\d+$"
      }
    })
    

    演示:https://mongoplayground.net/p/WdqTg7LCZIk


    我们也许可以找到这个问题的表达式。也许,让我们从类似于以下的表达式开始:

    product:\s+"(.+?)"
    

    Demo

    这里,我们使用product:\s+"作为左边界,然后我们收集任何字符,然后我们从右边界使用"

    const regex = /product:\s+"(.+?)"/gm;
    const str = `{
      name: "something"
      product: "ABC-123"
    }`;
    let m;
    
    while ((m = regex.exec(str)) !== null) {
        // This is necessary to avoid infinite loops with zero-width matches
        if (m.index === regex.lastIndex) {
            regex.lastIndex++;
        }
        
        // The result can be accessed through the `m`-variable.
        m.forEach((match, groupIndex) => {
            console.log(`Found match, group ${groupIndex}: ${match}`);
        });
    }

    或者我们可以将它扩展到我们喜欢捕获而不是捕获的内容:

    (?:product:\s+")(.+?)(?:")
    

    DEMO

    【讨论】:

      【解决方案2】:

      如果您的变化就是这样,而这就是您的 3 种可能性,那么 Emma 的答案正是您所需要的。如果正则表达式失控并且您最终拥有许多不同的产品变体,您还有另一个选择是$textsearch/index AND regEx。

      例如:

      db.getCollection('COLNAME').find({
        $or: [
          {
            $text: {$search: 'abc'}  // By default it is case insensitive
          },
          {
            product: {"$regex": "YOUR_REGEX_HERE"}
          }
        ]
      })
      

      这也是高效的,因为您将在 product 上拥有一个文本索引以及一个常规索引。这也将处理XXX-ABC 和您可能不知道/拥有的任何其他变体之类的情况。所以要考虑一下。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多