看文档里说明db.RegExp不支持用在db.command里,但目前我的需求是,在match阶段,针对3个字段or操作,正则匹配一个关键词,应该如何写?
报错如下:
errMsg: [FailedOperation] (Location15983) An object representing an expression must have exactly one field: { $regex: "关键词" , $options: "i" }; ; at cloud.callFunction api |
我大致的需求是这样的:
const reg = new db.RegExp({ regexp: '关键词' , options: 'i' , }) ... .match(_.expr( $.or([ $.eq([ '$nickName' , reg]), $.eq([ '$deliverInfo.userName' , reg]), $.eq([ '$deliverInfo.telNumber' , reg]) ]) )) |
我尝试不用$.or,先匹配一个字段也会报错
... .match(_.expr( $.eq([ '$nickName' , reg]), )) |
楼上大哥说的麻烦了吧。。。
.match($.or([
{
nickName:db.RegExp({
regexp: search || '.',
options: 'i',
}),
},
{
deliverInfo.userName:db.RegExp({
regexp: search || '.',
options: 'i',
}),
},
{
deliverInfo.userName:db.RegExp({
regexp: search || '.',
options: 'i',
}),
},
]))
你需要 or 的话,有点繁琐,请在云函数中使用
const _ = db.command
const $ = _.aggregate
const tb = '集合名称'
var rowsVar = ['$rows']
// field , kwd => 字段, 关键字
let getLookup = (field, kwd)=>{
var newVar = 'rows' + rowsVar.length
rowsVar.push('$'+newVar)
return {
from: tb,
pipeline: $.pipeline()
.match({
[field]: db.RegExp({
regexp: kwd,
options: 'i',
})
})
.done(),
as: newVar,
}
}
// 云函数入口函数
exports.main = async(event, context) => {
var keyword = '关键字'
return db.collection(tb).aggregate()
.match({
// 字段nickName正则匹配
nickName: db.RegExp({
regexp: keyword,
options: 'i',
})
})
.group({
_id: 'any',
rows: $.push('$$ROOT')
})
.lookup(getLookup('deliverInfo.userName', keyword)) // 字段deliverInfo.userName正则匹配
.lookup(getLookup('deliverInfo.telNumber', keyword)) // 字段deliverInfo.telNumber正则匹配
.addFields({
newRoot: $.concatArrays(rowsVar)
})
.unwind('$newRoot')
.replaceRoot({
newRoot: '$newRoot'
})
.end()
}
1、这样不会出现_id重复吗?
2、性能如何,如果直接做三次查询数据库查询,得到三个数组,再concat是不是也可以?
1,不会
2,可以