ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Laf 云数据库:用正则表达式对文本字段做模糊查询($regex 实战指南)

Laf 云数据库:用正则表达式对文本字段做模糊查询($regex 实战指南) Laf 云数据库用正则表达式对文本字段做模糊查询$regex 实战指南【免费下载链接】lafLaf is a vibrant cloud development platform that provides essential tools like cloud functions, databases, and storage solutions. It enables developers to quickly unleash their creativity and bring innovative ideas to life with ease.项目地址: https://gitcode.com/GitHub_Trending/la/laf本篇基于 Laf 官方文档 使用正则进行模糊查询 展开讲解如何在 Laf 云数据库lafjs/cloud的cloud.mongo.db驱动中使用正则表达式完成文本字段的模糊查询包括$regex基础用法、在$in中匹配多个正则、以及$not否定组合并结合仓库中 database-ql 查询序列化器、已废弃的 RegExp 工具类 与 where 单元测试 剖析正则条件从 JS 语法糖到最终{ $regex, $options }查询语句的底层转换链路。读完本文你可以直接在云函数中写出正确的正则查询并理解正则标志位、否定查询与数据库引擎Mongo / MySQL之间的适用边界。一、概述正则查询在 Laf 云数据库中的位置Laf 的云数据库通过lafjs/cloudSDK 暴露 Mongo 风格的数据库驱动。在云函数中通常这样拿到数据库句柄import cloud from lafjs/cloud const db cloud.mongo.db其中cloud.mongo是 SDK 中Cloud类的一个 getter从源码 packages/cloud-sdk/src/cloud.ts 可以看到它直接返回底层CloudSdkInterface提供的MongoDriverObject即 Mongo 风格驱动对象.collection(name)之后得到的集合支持find({ ... })这类标准 Mongo 查询条件对象。本文要解决的问题是当需要“名字包含某个字”“姓名以某姓开头”这类文本模糊匹配时如何用正则表达式RegExp表达查询条件。二、基础用法用$regex做包含匹配下面的示例查询users集合中所有名字中包含王的用户示例完整继承自官方文档import cloud from lafjs/cloud const db cloud.mongo.db export default async function () { const docs await db.collection(users) .find({ name: { $regex: /王/ } // 正则字面量名字中包含“王” }) .toArray() console.log(docs) }运行输出[ { _id: new ObjectId(65797a86f313010ca6017f6f), name: 王小波, age: 1000 }, { _id: new ObjectId(65797a86f313010ca6017f6f), name: 兰陵王, age: 30 } ]要点说明$regex操作符的值可以是JS 正则字面量如/王/也可以是字符串形式的正则表达式不加^、$锚点时/王/表示“任意位置包含”所以兰陵王也能命中正则标志位如i忽略大小写直接写在字面量后面例如/abc/i序列化时会原样带入见下一节底层实现。三、在$in操作符中使用多个正则当需要匹配“多个正则之一”时可以把正则数组直接作为$in的值。下面的示例查询所有姓王或陈即首字为王或陈的用户import cloud from lafjs/cloud const db cloud.mongo.db export default async function () { const docs await db.collection(users) .find({ name: { $in: [/^王/, /^陈/] } // 两个正则以“王”开头 或 以“陈”开头 }) .toArray() console.log(docs) }运行输出[ { _id: new ObjectId(65797a86f313010ca6017f6f), name: 王小波, age: 1000 }, { _id: new ObjectId(65797a86f313010ca6017f6f), name: 陈奕迅, age: 40 } ]这里的关键是^锚点/^王/限定“王”必须出现在字符串开头因此兰陵王虽然含王但不会命中。$in 正则数组是“多模式前缀匹配”的简洁写法避免了显式的$or。四、$regex与$not组合否定查询如果需要查询“不姓王”的用户可以用$not包裹$regeximport cloud from lafjs/cloud const db cloud.mongo.db export default async function () { const docs await db.collection(users) .find({ name: { $not: { $regex: /^王/ } } // 名字不以“王”开头 }) .toArray() console.log(docs) }运行输出[ { _id: new ObjectId(65797a86f313010ca6017f6f), name: 陈奕迅, age: 40 }, { _id: new ObjectId(65797a86f313010ca6017f6f), name: 兰陵王, age: 30 } ]注意输出中兰陵王仍在结果里——因为$not否定的是/^王/以“王”开头而兰陵王只是“包含”王而非“以王开头”。编写否定查询时务必把锚点写清楚否则语义会出乎意料。五、底层实现JS 正则如何被序列化为$regex/$options上面的查询之所以可以直接写/^王/这样的字面量是因为 Laf 的查询条件序列化器database-ql会自动把原生RegExp对象编码为 Mongo 查询语法。核心逻辑在 packages/database-ql/src/serializer/query.tsencodeRegExp(query: RegExp) { return { $regex: query.source, // 取正则的 pattern 部分去掉 / 与标志位 $options: query.flags, // 取标志位如 i、g、m } }也就是说你在代码里写的/^王/i最终会变成查询文档{ $regex: ^王, $options: i }发给数据库引擎执行。source与flags都是 JSRegExp实例的标准属性因此正则的所有标志位i忽略大小写、m多行等都会被完整保留。对于第四节的否定写法序列化器在逻辑命令分支中有专门处理同文件当$not的操作数本身是一个RegExp通过isRegExp判断时会调用encodeRegExp生成{ fieldName: { $not: { $regex, $options } } }结构再与普通查询条件合并。这与 MongoDB 官方$not的语义一致。该转换链路有单元测试覆盖见 packages/database-ql/tests/units/get/where.test.js 中的where() with RegExp should be ok用例用例同时覆盖了字符串写法db.RegExp({ regexp: ^abc.*$ })、原生new RegExp(^abc.*$, i)以及正则字面量断言它们最终都序列化为{ $regex: ^abc.*$, $options: ... }形式的查询条件。六、注意旧的db.RegExp(...)构造方式已废弃在早期版本的 SDK 中正则需要通过db.RegExp({ regexp, options })构造。从源码 packages/database-ql/src/regexp/index.ts 可以看到该RegExp类及其构造函数RegExpConstructor均已标注deprecated注释明确提示“use js nativeRegExpinstead”改用 JS 原生RegExp。因此新代码推荐直接使用正则字面量或new RegExp(pattern, flags)它们都会被序列化器原生识别无需经过废弃的包装类// 推荐 find({ name: { $regex: /^王/i } }) find({ name: { $regex: new RegExp(^王, i) } }) // 已废弃仅兼容旧代码 find({ name: db.RegExp({ regexp: ^王, options: i }) })七、适用边界Mongo 驱动 vs MySQL 引擎本文所有示例都基于cloud.mongo.dbMongo 风格驱动。需要注意 Laf 的数据库代理层同时支持 Mongo 与 MySQL 两种引擎从 packages/database-proxy/src/accessor/sql_builder.ts 的操作符映射表看SQL 路径支持的查询操作符包括、、、、、、in、not in以及 SQL 专用的$like见 packages/database-proxy/src/types.ts 中LIKE: $like // only for SQL query的注释映射表中并没有$regex分支。由此可以推断$regex正则模糊查询适用于Mongo 引擎 /cloud.mongo驱动场景本文所有示例均以此为前提若查询目标数据库由 MySQL 引擎承载模糊匹配应使用 SQL 语义的$like操作符%、_通配而非正则语法编写跨引擎的代码时建议先确认目标集合实际绑定的数据库类型再选择等价的模糊匹配方式。八、常用正则速查结合本文示例需求查询条件说明包含“王”name: { $regex: /王/ }任意位置匹配以“王”开头name: { $regex: /^王/ }^锚定开头以“波”结尾name: { $regex: /波$/ }$锚定结尾姓“王”或“陈”name: { $in: [/^王/, /^陈/] }多正则之一命中不姓“王”name: { $not: { $regex: /^王/ } }否定前缀匹配忽略大小写name: { $regex: /^wang/i }i标志位随flags序列化正则语法本身遵循 JavaScript 标准ECMAScript RegExp标志位如i忽略大小写、g全局、m多行等均可通过flags原样传给引擎编写复杂模式时可自行查阅 MDN 的正则表达式参考或 MongoDB 官方$regex文档。小结Laf 云数据库中文本模糊查询直接使用 JS 原生正则$regex: /pattern/flags序列化器会自动转换为{ $regex, $options }查询语句序列化实现$in可接收正则数组实现“多个前缀/模式任一命中”的简洁写法$not包裹$regex实现否定查询注意锚点语义旧版db.RegExp({ regexp, options })构造方式已标记废弃新代码统一使用原生RegExp$regex面向 Mongo 引擎与cloud.mongo驱动MySQL 引擎的模糊匹配使用$like操作符编写查询前先确认目标数据库类型更多云数据库查询语法比较、逻辑操作符等可继续查阅 docs/zh/cloud-database/query/ 目录及 云数据库总览。【免费下载链接】lafLaf is a vibrant cloud development platform that provides essential tools like cloud functions, databases, and storage solutions. It enables developers to quickly unleash their creativity and bring innovative ideas to life with ease.项目地址: https://gitcode.com/GitHub_Trending/la/laf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表