mongodb $regex 中排序规则的使用

2023-11-21

由于 v3.4 排序规则可用于查找操作,尤其是在涉及变音符号匹配时。虽然具有确定值($eq 运算符或相应构造)的查找查询将匹配字母和相应的变音符号,但如果使用 $regex 来实现部分搜索字符串(“LIKE”)的匹配,则情况并非如此。 )。

是否可以使 $regex 查询以与 $eq 查询相同的方式使用排序规则?

考虑示例集合 testcoll:

{ "_id" : ObjectId("586b7a0163aff45945462bea"), "city" : "Antwerpen" }, 
{ "_id" : ObjectId("586b7a0663aff45945462beb"), "city" : "Antwërpen" }

此查询将找到两条记录

db.testcoll.find({city: 'antwerpen'}).collation({"locale" : "en_US", "strength" : 1});

使用正则表达式的相同查询不会(仅查找包含“Antwerpen”的记录)

db.testcoll.find({city: /antwe/i}).collation({"locale" : "en_US", "strength" : 1});

我今天遇到了同样的问题,我疯狂地搜索互联网试图找到解决方案。没有找到。所以我想出了我的解决方案,一个对我有用的小弗兰肯斯坦。

我创建了一个函数,它从字符串中删除所有特殊字符,然后将所有可能特殊的字符替换为可能特殊的等效正则表达式。最后我只是添加一个"i"选项来覆盖我的数据库中的大写字符串。

export const convertStringToRegexp = (text: string) => {
  let regexp = '';
  const textNormalized = text
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '') // remove all accents
    .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') // remove all regexp reserved char
    .toLowerCase();

  regexp = textNormalized
    .replace(/a/g, '[a,á,à,ä,â,ã]')
    .replace(/e/g, '[e,é,ë,è,ê]')
    .replace(/i/g, '[i,í,ï,ì,î]')
    .replace(/o/g, '[o,ó,ö,ò,õ,ô]')
    .replace(/u/g, '[u,ü,ú,ù,û]')
    .replace(/c/g, '[c,ç]')
    .replace(/n/g, '[n,ñ]')
    .replace(/[ªº°]/g, '[ªº°]');
  return new RegExp(regexp, 'i'); // "i" -> ignore case
};

而在我的find()方法,我只是使用这个函数$regex选项,像这样:

db.testcoll.find({city: {$regex: convertStringToRegexp('twerp')} })

/*
Output:
[
  { "_id" : ObjectId("586b7a0163aff45945462bea"), "city" : "Antwerpen" }, 
  { "_id" : ObjectId("586b7a0663aff45945462beb"), "city" : "Antwërpen" }
]
*/

我还创建了一个.spec.ts文件(使用 Chai)来测试此功能。当然,你可以适应 Jest。


describe('ConvertStringToRegexp', () => {
  it('should convert all "a" to regexp', () => {
    expect(convertStringToRegexp('TAÁdaáh!')).to.deep.equal(
      /t[a,á,à,ä,â,ã][a,á,à,ä,â,ã]d[a,á,à,ä,â,ã][a,á,à,ä,â,ã]h!/i
    );
  });
  it('should convert all "e" to regexp', () => {
    expect(convertStringToRegexp('MEÉeéh!')).to.deep.equal(
      /m[e,é,ë,è,ê][e,é,ë,è,ê][e,é,ë,è,ê][e,é,ë,è,ê]h!/i
    );
  });
  it('should convert all "i" to regexp', () => {
    expect(convertStringToRegexp('VÍIiishí!')).to.deep.equal(
      /v[i,í,ï,ì,î][i,í,ï,ì,î][i,í,ï,ì,î][i,í,ï,ì,î]sh[i,í,ï,ì,î]!/i
    );
  });
  it('should convert all "o" to regexp', () => {
    expect(convertStringToRegexp('ÓOoóhhhh!!!!')).to.deep.equal(
      /[o,ó,ö,ò,õ,ô][o,ó,ö,ò,õ,ô][o,ó,ö,ò,õ,ô][o,ó,ö,ò,õ,ô]hhhh!!!!/i
    );
  });
  it('should convert all "u" to regexp', () => {
    expect(convertStringToRegexp('ÚUhuuúll!')).to.deep.equal(
      /[u,ü,ú,ù,û][u,ü,ú,ù,û]h[u,ü,ú,ù,û][u,ü,ú,ù,û][u,ü,ú,ù,û]ll!/i
    );
  });
  it('should convert all "c" to regexp', () => {
    expect(convertStringToRegexp('Cacacacaca')).to.deep.equal(
      /[c,ç][a,á,à,ä,â,ã][c,ç][a,á,à,ä,â,ã][c,ç][a,á,à,ä,â,ã][c,ç][a,á,à,ä,â,ã][c,ç][a,á,à,ä,â,ã]/i
    );
  });
  it('should remove all special characters', () => {
    expect(
      convertStringToRegexp('hello 123 °º¶§∞¢£™·ª•*!@#$%^WORLD?.')
    ).to.deep.equal(
      /h[e,é,ë,è,ê]ll[o,ó,ö,ò,õ,ô] 123 [ªº°][ªº°]¶§∞¢£™·[ªº°]•\*!@#\$%\^w[o,ó,ö,ò,õ,ô]rld\?\./i
    );
  });
  it('should accept all regexp reserved characters', () => {
    expect(
      convertStringToRegexp('Olá [-[]{}()*+?.,\\o/^$|#s] Mundo! ')
    ).to.deep.equal(
      /* eslint-disable @typescript-eslint/no-explicit-any */
      /[o,ó,ö,ò,õ,ô]l[a,á,à,ä,â,ã] \[-\[\]\{\}\(\)\*\+\?\.,\\[o,ó,ö,ò,õ,ô]\/\^\$\|#s\] m[u,ü,ú,ù,û][n,ñ]d[o,ó,ö,ò,õ,ô]! /i
    );
  });
});

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mongodb $regex 中排序规则的使用 的相关文章

随机推荐

  • 鼠标中键按下并移动事件

    是什么控制事件鼠标中键按下并移动 也就是说 当我按住鼠标中键并移动鼠标时 我可以订阅什么事件 看一下 Control MouseDown 事件 鼠标按钮枚举 在 C 中检测鼠标按钮事件 你也可以尝试这样的事情 private void Fo
  • 使用 Redis 的 Mule 缓存策略

    我正在寻找一种在两台服务器之间共享缓存的方法 并且正在研究使用 Redis 作为对象存储缓存策略 但在读取存储值时遇到问题 当缓存命中为未命中值时 它会成功存储值 但在检索该值时会抛出错误 所需的对象 属性 muleContext 为 nu
  • 如何在 ext 4 中制作完整的模式窗口?

    就像微软操作系统 xp vista 7 等 中的窗口一样 如果主窗口创建模态窗口 则用户无法访问主窗口 包括关闭和访问工具栏等 我想用 extjs 做一个类似的 这是我的模态示例 Ext create Ext Window title aa
  • 类型存在于 2 个程序集中

    我从两个不同的第三方 COM DLL 创建了两个 NET Interop 程序集 这两个 COM DLL 都包含一个名为COMMONTYPE 所以 COMMONTYPE现在也通过两个互操作程序集公开 我有第三个项目需要使用这两个互操作程序集
  • jce 无法验证提供者 bc

    我开发了一个应用程序 在 BountyCastle jar 的帮助下使用了密码学 我还有一行 Security addProvider new org bouncycastle jce provider BouncyCastleProvid
  • 在两个无序字符向量之间执行非成对的全部比较 --- intersect 的相反 --- 全部到全部 setdiff

    示例数据 v1 lt c E82391 X2329323 C239923 E1211 N23932 F93249232 X93201 X9023111 O92311 9000F K9232932 L9232932 X02311111 v2
  • Object类如何实现clone()方法

    在一本关于 Core Java 的书中 我发现了这样的摘录 想想以何种方式 对象类可以实现克隆 它 对物体一无所知 所以它只能逐个字段 复制 如果对象中的所有数据字段 是数字或其他基本类型 复制字段就可以了 但 如果该对象包含对 子对象 然
  • 在调用超类构造函数之前验证构造函数的参数

    例如 这样的构造函数 public class Car extends Vehicle public Car Car a super a getName what if a is null 在调用 super 之前我无法检查参数的条件 在这
  • 用自定义的任务计划程序替换 C# 中的任务计划程序

    我想知道是否可以使用 C 更改将任务映射到 NET 中真实操作系统线程的任务调度程序 或者是否需要重新编译 Mono 运行时来执行此操作 谢谢 系统 线程 任务 如果您参考系统 线程 任务那么你需要的是子类化任务调度器然后你可以使用你的类的
  • 参数类型“customClass.Type”不符合预期类型“NSItemProviderWriting”

    iOS 11 x 斯威夫特 4 尝试实现自定义类以使用新的拖放协议 并且需要一些超级编码器的帮助 我创建了这个类 import UIKit import MobileCoreServices class CustomClass NSObje
  • PHP 的 mail():有哪些需要注意的潜在问题?

    给定接受自定义用户输入 例如地址 主题行 消息 的联系表单 需要注意哪些安全隐患和 陷阱 至少 必须验证用户的电子邮件地址 可能使用 filter var 或等效函数 根据我的阅读 这还应该防止将额外的标头注入到脚本中 那么主题行和消息内容
  • angular-cli工具的--base-href和--deploy-url参数有什么区别

    Angular 的文档告诉我们应该使用 base href当要部署在子文件夹中时 Angular 应用程序构建用于生产时的参数 如果将文件复制到服务器子文件夹中 请附加构建标志 base href并设置适当地 例如 如果index html
  • golang 中 C++ 的“using”等价物是什么

    什么是C using some namespace objectgolang 中的等价物 根据问题here我可以得到using namespace common附有以下声明 import common 但这会导入整个命名空间 现在我只想使用
  • force_ssl 在 Rails 中做什么?

    在之前的一个question我发现我应该设置 nginx ssl 终止并且不让 Rails 处理加密数据 那么为什么会出现下面的情况呢 config force ssl true 我在生产配置文件中看到这一点被注释掉了 但是 如果期望 ng
  • PyInstaller 打包的应用程序在控制台模式下工作正常,在窗口模式下崩溃

    我正在使用 Python 和 PySide 构建一个相当复杂的应用程序 发布的日子终于临近了 所以我想将此应用程序构建为 exe 然而 我手上有一个奇怪的问题 我过去使用过 PyInstaller 顺便说一下 使用版本 2 但从未发生过这种
  • 如何以编程方式编译和实例化 Java 类?

    我将类名存储在属性文件中 我知道类存储将实现 IDynamicLoad 如何动态实例化该类 现在我有 Properties foo new Properties foo load new FileInputStream new File C
  • 在 Subversion 中替换整个目录树的最佳方法?

    在我的 Subversion 项目中 我有一些目录 其中包含我的代码所需的其他开源项目 例如 ffmpeg freetype matrixssl 和其他一些 更新 SVN 以保存这些项目之一的最新版本的最佳方法是什么 本质上我将执行以下操作
  • 什么机制允许 ViM 暂时覆盖整个控制台?

    当你进入vim 它 清除 屏幕 退出后 它会 恢复 原始内容 我知道可以使用 x1b 2J清除控制台并重置光标位置 但这将覆盖终端内容 我假设 Vim 使用ncurses在幕后 我想更好的问题是 ncurses 如何做到这一点 但它是如何完
  • 当 UAC 被拒绝时 Process.Start 永远不会返回

    我有一个更新程序 exe 旨在关闭主 exe 将其替换为更新的 exe 然后启动该更新的 exe 当更新程序尝试启动更新的 exe 时 如果用户拒绝 UAC 权限对话框 更新程序将挂起 这是因为Process Start 函数永远不会返回
  • mongodb $regex 中排序规则的使用

    由于 v3 4 排序规则可用于查找操作 尤其是在涉及变音符号匹配时 虽然具有确定值 eq 运算符或相应构造 的查找查询将匹配字母和相应的变音符号 但如果使用 regex 来实现部分搜索字符串 LIKE 的匹配 则情况并非如此 是否可以使 r