timzaak / blog

8 stars 1 forks source link

ElasticSearch 快速理解 #88

Closed timzaak closed 2 years ago

timzaak commented 2 years ago

ElasticSearch 的调试UI界面可选用官方的 Kibana ,或者_head chrome 插件。

这里贴一个带注释的请求片段,囊括 ES 的大部分应用场景

# 查看所有索引
GET _cat/indices

# 创建索引
PUT test_1
{
  "settings": {
    "similarity": {
      "word_count": {
        "type": "scripted",
        "script": {
          "source": "term.docFreq"
        }
      }
    }
  }, 
  "mappings": {
    "properties": {
      "d": {
        "type": "text",
        "similarity": "word_count",
        "analyzer": "whitespace"
      }
    }
  }
}

# 查看创建的索引
GET test_1/_mapping

# 调试分词,可查看 text 的分词结果
GET /_analyze
{
  "tokenizer": "whitespace", 
  "text": "鳜鱼 去头 去尾 去骨 鱼肉 刺 鱼尾 鱼骨",
  "explain": true,
  "attributes": "keyword"
}

similarity 在 ES 里是算分数的,这里定制了一下, word_count:根据词频算分数,命中多少个词(term),就算多少分。 analyzer 在 ES 里是管分词的,中文一般用IK、jieba 等,这里为了演示用 空格 来分词。 但是索引若是更改,用 _reindex 来迁移。

# 插入数据
PUT test_1/_doc/1
{"d": "鳜鱼 去头 去尾 去骨 鱼肉 刺 鱼尾 鱼骨"}

ES 也支持批量插入 _bulk

# 按 term 去查, match 是在 term 查询的基础上,多了对查询条件的分词
GET test_1/_search?explain=true
{
  "from":0,
  "size":20,
  "query": {
    "term": {
      "d": "鳜鱼"
    }
  }
}

# score:2

注意 similarity 设置的是基础分,如果需要对分(排序)进行二次定制,例如:多 Field 查询,每个 Field 要不同的权重。可看看 function_score 的文档。

当有索引变化的需求时,需要通过 _reindex、alias 来做索引更新, 但这时候要考虑新增/修改/删除数据该怎么办的问题,需要二次补偿,最好记录数据ID。

IK 分词虽然支持动态添加、删除 term 操作,但是不会对老文档产生影响,需要手动更新一遍老文档,或是重建索引。 手动更新可通过 _update_by_query + 脚本 来完成。推荐用手动更新来做。

小结

对于搜索来讲,要知道 tokenizer 、term、similarity 三个词在 ES 中所代表的含义, 其它都是在此基础上的拓展,至于分片、 集群,就当是任务分发、结果合并等常规的分布式数据库的功能来看待好了。

timzaak commented 2 years ago

Aggregations

聚合在 ES 中由三块组成:Bucket, Metrics, Pipeline.

Bucket

可以简单理解为 SQL 中的 group by, 它也提供 join(parent) 来做 文档的父子关系,拓展 group by 的边界。

Metrics

可以简单理解为Map Reduce,例如Top几、总分、中位数等,scripted_metric 可以写 painless script,以代码的形式来描述其Map Reduce过程。不过尽量还是用ES已有的 API 比较好,性能会好一些。

Pipeline

是在 Bucket Aggregations 的结果集上,做二次结算,例如 bucket_script, 能从脚本中拿到 bucket 的 Metrics 计算结果。