prisma中where对象转换RedisJson查询字符串

输入

{
    "where": {
        "number": {
            "gt": 35
        },
        "OR": [
            {
                "name1": {
                    "startsWith": "ssss"
                },
                "name2": {
                    "not": {
                        "contains":"22"
                    }
                },
                "name3": "35"
            },
            {
                "name1": "35"
            }
        ]
    }
}

转换代码

注:图中所使用的的函数是lodash的函数

import { concat, isArray, template } from 'lodash';
export class Builder {
    static generateWhere(condition: object, name?: string, negate?: string) {
    let arr = [];
    // key是prisma where条件中的关键词,value值是lodash中模板字符串
    const kvMap = new Map([
      ['contains', '(<%=negate%>@<%=key%>_ext:{<%=value%>})'],
      ['startsWith', '(<%=negate%>@<%=key%>_ext:{<%=value%>*})'],
      ['equals', '(<%=negate%>@<%=key%>:{<%=value%>})'],
      ['gt', '(<%=negate%>@<%=key%>:[(<%=value%> +inf])'],
      ['lt', '(<%=negate%>@<%=key%>:[-inf (<%=value%>])'],
      ['lte', '(<%=negate%>@<%=key%>:[-inf <%=value%>])'],
      ['gte', '(<%=negate%>@<%=key%>:[<%=value%> +inf])'],
      ['in', '(<%=negate%>@<%=key%>:{<%=value.join("|")%>})'],
    ]);
    // 使用map简化if else代码
    for (const [key, value] of Object.entries(condition)) {
      if (kvMap.has(key)) {
        const compiled = template(kvMap.get(key));
        // 编译模板字符串
        arr.push(
          compiled({
            key: name,
            value: value,
            negate: negate,
          })
        );
      } else if (key === 'AND') {
        /// 是AND,就继续递归
        if (isArray(value)) {
          if (value.length !== 1) {
            arr.push('(');
          }
          for (const it of value) {
            arr = concat(arr, this.generateWhere(it));
          }
          if (value.length !== 1) {
            arr.push(')');
          }
        } else {
          arr.push('(');
          arr = concat(arr, this.generateWhere(value));
          arr.push(')');
        }
      } else if (key === 'OR') {
        /// 是OR,就继续递归
        /// 如果是 OR:[{"name1":"222"}]
        if (isArray(value) && value.length === 1) {
          arr = concat(
            arr,
            this.generateWhere({
              OR: value[0],
            })
          );
        } else if (isArray(value) && value.length > 1) {
          for (let i = 0; i < value.length; i++) {
            arr = concat(arr, this.generateWhere({ OR: value[i] }));
          }
        } else if (UtilGroup.isObject(value)) {
          if (Object.keys(value).length === 1) {
            arr.push('|');
          } else {
            arr.push('|(');
          }
          arr = concat(arr, this.generateWhere(value));
          if (Object.keys(value).length !== 1) {
            arr.push(')');
          }
        }
      } else if (key === 'not') {
        /// 是对象,就继续递归
        if (UtilGroup.isString(value)) {
          const temp = {};
          temp[`${name}`] = value;
          arr = concat(arr, this.generateWhere(temp, undefined, '-'));
        } else {
          arr = concat(arr, this.generateWhere(value, name, '-'));
        }
      } else if (UtilGroup.isObject(value)) {
        /// 是对象,就继续递归
        arr = concat(arr, this.generateWhere(value, key));
      } else {
        if (negate) {
          arr.push(`(${negate}@${key}:{${value}})`);
        } else {
          arr.push(`(@${key}:{${value}})`);
        }
      }
    }
    return arr;
  }

  /**
   * 判断是否是对象
   * @param value
   */
  static isObject(value: any) {
    return Object.prototype.toString.call(value) === '[object Object]';
  }

  /**
   * 判断是否是字符串
   * @param value
   */
  static isString(value: any) {
    return Object.prototype.toString.call(value) === '[object String]';
  }
}

调用

const data: string = Builder.generateWhere(params).join('');

输出

(@number:[(35 +inf])|((@name1_ext:{ssss*})(-@name2_ext:{22})(@name3:{35}))|(@name1:{35})

推荐

redis-om
prisma

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值