其他分享
首页 > 其他分享> > 新增字段需求的实现和优化

新增字段需求的实现和优化

作者:互联网

搜索查询优化

背景描述:

项目是一个崩溃分析平台,原来的 搜索功能 是通过mongodb来实现的,后面数据量变得越来越大,mongodb的搜索速度也太慢了,还有有一些搜索类似于查日志了,mongodb默认的经常查不到相关数据,后面慢慢使用mongodb+es混合查询来实现,性能也有了保证.

需求描述:

想在原有的一些字段上再加上一些新增字段

碰到的问题以及解决办法

1. es 查询太慢

大部分的字段查询时间可以控制在 500毫秒左右,但是有一些字段查询时间长达 10秒.
经过分析,知道了这些字段内容大部分重复的有很多,比如有一个查询字段是 Android版本,如果查找 11 耗时非常慢

优化点

  1. 发现默认查询的条数 是 1万条,实际使用是不需要这么多的,改成2000条后查询时间基本上降到了5秒内
  2. 默认使用的是must查询方式,这种查询方式查询完后会影响相关性得分,给出不同的排名,并且不会缓存结果,改成filter 查询可以进一步优化
  3. 原来的逻辑是es需要查询两次,因为两个数据不是在一张表,先查询表 a,查询出表a的自定义id字段后,再去拿a表的自定义id字段查询表b,得到最后结果,这里发现es查询到a表的自定义id字段有很多都是重复的,其实这些重复的字段只查询一次就可以了
    简单来说就是去重,也能减少第二次查询的时间,百度了一些有好几种方式,试了一下效果都不理想,或者需要单独配置es(没有配置权限),后面百度到可以新增一个参数
          // 数据去重
          collapse: {
            field: 'crashuid'// 相关去重字段
          }

通过这一步优化可以把查询时间降到3秒以内
4. 其他还碰到一些小问题,比如字段查询不到 将 term 换成 match_phrase,查询数组要用terms等

2. mongodb 查询不到结果

  1. 发现请求里面有特殊字符串 / 在解析的时候当成动态路由了,导致前端路由匹配失败,请求报错404,解决办法,使用encodeURIComponent()前后端进行解析
    但是因为参数是个对象格式的,如果每个变量都包装一下,代码会变得很丑,于是封了一个方法
// 转义对象中的特殊字符
const encodeObject = (obj) => {
  if (!isObject(obj)) {
    return obj;
  }
  return Object.keys(obj).reduce((acc, key) => {
    acc[key] = encodeValue(obj[key]);
    return acc;
  }, {});
};

// 解码对象中的特殊字符
const decodeObject = (obj) => {
  if (!_.isObject(obj)) {
    return obj;
  }
  return Object.keys(obj).reduce((acc, key) => {
    acc[key] = decodeValue(obj[key]);
    return acc;
  }, {});
};
  1. 改完之后发现某些还是查询不到结果,后面发现了,mongodb使用的是正则查询的方式,前端传过来的字符串如果含有正则特殊符号会导致匹配失败
    这里需要进行转换
// 转义对象中含有正则中的特殊字符
const escapeRegExpObject = (obj) => {
  if (!_.isObject(obj)) {
    return obj;
  }
  return Object.keys(obj).reduce((acc, key) => {
    acc[key] = _.escapeRegExp(obj[key]);
    return acc;
  }, {});
};

感悟

本次需求完成后,发现刚开始以为需求只是一个小小的功能,2天就能完事,在做的过程中发现没考虑到的东西越来越多,特别有一些是数据库方面的
对这方面的知识也恶补了一下,总之还是挺有收获的

标签:需求,acc,return,mongodb,新增,查询,key,obj,优化
来源: https://www.cnblogs.com/qisexin/p/16351921.html