ElasticSearch玄学问题

排序

"sort" : [
  "_score",
  {"created_at": "desc"}
]

// 多值字段,选择处理模式,这里是取平均值
"sort" : [
  {"price": {"order" : "asc", "mode" : "avg"}}
]

// 缺失字段的记录排最后
"sort" : [
  {"price": {"missing": "_last"} }
],

距离降权排序

{
  "query": {
    "function_score": {
      "query": {
        "term": {
          "city_id": 110000
        }
      },
      "functions": [{
        "gauss": {
          "geo_location_loc": {
            "origin": "39.908006,116.297453",
            "scale": "10km",
            "offset": 0,
            "decay": 0.2
          }
        }
      }]
    }
  },
  "script_fields": {
    "distance": {
      "script": "doc['geo_location_loc'].arcDistance(39.908006,116.297453)"
    }
  }
}
  1. 使用 ES 提供的衰减函数计算距离带来的权重影响

  2. script 中使用 groovy 脚本计算距离进行返回

同义词配置

{
  "index": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "synonyms_path": "analysis/synonym.txt",
          "type": "synonym"
        }
      },
      "analyzer": {
        "ik_syno": {
          "filter": [
            "my_synonym_filter"
          ],
          "type": "custom",
          "tokenizer": "ik_max_word"
        }
      }
    }
  }
}

索引优化

  1. 批量索引时,关闭elasticsearch备份,刷新时间设置为-1

  2. 使用bulk批量索引数据

  3. 使用单生产者扫表,多消费者建立es索引

  4. 使用SSD,相较HDD性能可提升3倍

1. {"refresh_interval": -1, number_of_replicas: 0}

查询优化

一般

  1. 在数据量比较大的时候,可以分片,将每个分片的数据量控制在百万级别;使用指定的字段值作为路由,查询的时候带上路由。

  2. 查询条件中不要使用变量,如时间查询中的 now, 这样不会缓存结果

  3. 对只读索引进行强制合并段 _optimize

GEO

  1. 为避免将所有的坐标点都加载到内存中,可以使用 geo_bounding_box 来优化查询

  2. 在精度要求不是很高的情况下,可以降低精度

  3. 坐标过滤的代价相对较为昂贵,可以使用其他条件过滤出一个较小的数据集,再使用坐标过滤

{
  "location": {
    "type": "geo_point",
    "fielddata": {
      "format":    "compressed",
      "precision": "1km"
    }
  }
}

标签: none

添加新评论