uniCloud中用new RegExp(keyword, 'i')实现单字段模糊匹配最轻量,需转义特殊字符、避免/g标志;多字段用dbCmd.or()显式“或”逻辑;多字拆分用|拼接并转义;聚合查询须在match中用$or且skip/limit放其后。

uniCloud where 中用 new RegExp() 做基础模糊匹配
直接在 where 条件里传正则对象是最常用、最轻量的模糊查法,适合单字段、单关键词、不区分大小写的场景。比如用户搜“张三”,想匹配“张三丰”“小张三”“李张三”。
关键点是:必须用 new RegExp(keyword, 'i'),不能写成字面量 /keyword/i(云数据库不识别动态变量);'i' 表示忽略大小写,'g' 在单次查询中无实际作用,可省略。
-
keyword必须提前做安全过滤,避免正则特殊字符(如.、*、^)导致语法错误或意外匹配,建议用keyword.replace(/[.*+?^${}()|[]\]/g, '\$&')转义 - 只支持对字符串字段生效,对数字、日期、对象字段无效
- 数据库索引对正则查询基本无效,数据量大时响应明显变慢
- 示例:
db.collection('user').where({ name: new RegExp('张三', 'i') }).get()
多字段 or 匹配用 dbCmd.or() + 多个 new RegExp()
当需要在 title 或 content 任一字段中出现关键词时,不能写成 { title: /xxx/, content: /xxx/ }(这是 and 逻辑),得用 dbCmd.or() 显式声明“或”关系。
注意:dbCmd.or() 的每个子条件必须是完整对象,不能把正则直接塞进数组里;且各字段的正则要分别构造,不能共用一个实例(虽然不影响结果,但易读性差)。
- 错误写法:
dbCmd.or([{ title: reg }, { content: reg }])——dbCmd.or()不接受数组,会报Invalid parameter - 正确写法:
dbCmd.or({ title: new RegExp(kw, 'i') }, { content: new RegExp(kw, 'i') }) - 如果字段值含换行符或空格,
'i'仍有效,但默认不跨行匹配;如需匹配换行,得加's'标志(uniCloud 当前版本支持) - 示例:
.where(dbCmd.or({ title: new RegExp('云开发', 'i') }, { desc: new RegExp('云开发', 'i') }))
用户输入多字时实现“任意一字匹配”——拆字转 | 正则
用户搜“家啊”,希望匹配到“啊!你家呢”这类含任意一个字的记录,本质是“字符级 or”,需把输入字符串逐字拆开、用 | 拼接成正则。
这种写法简单粗暴,但要注意中文字符边界和重复字问题。比如输“你好你”,split("") 会变成 "你|好|你",虽不影响匹配,但正则表达式冗余;更稳妥的是先去重再 join。
- 必须对每个字单独转义,否则像“.”“[”这类字会破坏正则结构
- 推荐处理链:
Array.from(keyword).map(c => c.replace(/[.*+?^${}()|[]\]/g, '\$&')).join('|') - 最终正则形如
new RegExp('你|家|啊', 'i'),放进where或dbCmd.or都可以 - 性能风险高:4 字输入就生成 4 分支正则,10 字以上查询延迟显著上升,慎用于高频搜索框
聚合查询 aggregate 中的正则匹配与分页陷阱
当需要结合分页、排序、去重等复杂逻辑时,aggregate 比 where 更可控,但正则写法位置和行为有差异:必须放在 match 阶段,且不能用 dbCmd.or(),得靠 $or 操作符。
容易忽略的一点是:聚合管道里的 skip/limit 必须放在 match 之后,否则会先分页再过滤,导致漏数据。另外,aggregate 不支持 clientDB 的响应式更新,只适合后端云函数调用。
-
match内写$or: [ { title: { $regex: keyword, $options: 'i' } }, { content: { $regex: keyword, $options: 'i' } } ] - 不要在
match前加skip,否则分页失效 - 云函数中用
aggregate可避免前端暴露数据库结构,安全性更高 - 示例片段:
.aggregate().match({ $or: [...] }).skip(0).limit(20).end()


















