收藏
回答

db.RegExp如何用在多字段or操作里?

看文档里说明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]),
      ))


最后一次编辑于  11-06
回答关注问题邀请回答
收藏

1 个回答

  • o0o有脾气的酸奶
    o0o有脾气的酸奶
    11-06

    你需要 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()

        }

    11-06
    赞同 1
    回复 8
    • 郑旭东
      郑旭东
      11-06
      谢谢,叹为观止,涨姿势了,有两个疑问:

      1、这样不会出现_id重复吗?

      2、性能如何,如果直接做三次查询数据库查询,得到三个数组,再concat是不是也可以?
      11-06
      回复
    • o0o有脾气的酸奶
      o0o有脾气的酸奶
      11-06回复郑旭东
      上面的查询只为满足你的问题需求,性能问题自己权衡
      1,不会
      2,可以
      11-06
      回复
    • 郑旭东
      郑旭东
      11-06回复o0o有脾气的酸奶
      翻车了,我其中两个字段deliverInfo.userName,deliverInfo.telNumber,是通过lookup另外一张表得到的字段,不是主表字段。所以方案中后面两个lookup不管用...
      11-06
      回复
    • 郑旭东
      郑旭东
      11-06
      另外我谨慎怀疑方案中三个数组中会有_id重复,因为只要分别符合匹配条件的记录都进来了,没看到哪里有排重的操作哦。
      11-06
      回复
    • o0o有脾气的酸奶
      o0o有脾气的酸奶
      11-06回复郑旭东
      哦,忘记你的是同个关键字了,那很有可能有问题
      11-06
      回复
    查看更多(3)
问题标签