Python社区  »  MongoDB

MongoDB查询以查找可能具有查询字符串变体的文档

James Lim • 2 年前 • 473 次点击  

MongoDB文档示例:

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

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

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

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

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/56741
 
473 次点击  
分享到微博
文章 [ 2 ]  |  最新文章 2 年前
Akrion
Reply   •   1 楼
Akrion    2 年前

如果你的变化就是这三种可能性,那么 艾玛 正是你所需要的。如果正则表达式失控,而最终导致 $text 搜索/索引和正则表达式。

例如:

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

这也可以执行,因为您将在 product 以及常规索引。这也会处理像 XXX-ABC 以及其他你可能不知道的变化。所以有些事情要考虑。

Emma
Reply   •   2 楼
Emma    2 年前

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

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

enter image description here