社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  MongoDB

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

James Lim • 6 年前 • 2484 次点击  

MongoDB文档示例:

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

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

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

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

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/56741
文章 [ 2 ]  |  最新文章 6 年前
Akrion
Reply   •   1 楼
Akrion    7 年前

如果你的变化就是这三种可能性,那么 艾玛 正是你所需要的。如果正则表达式失控,而最终导致 是 $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    7 年前

编辑: 你可以简单地使用 $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