博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
全文检索工具elasticsearch
阅读量:3967 次
发布时间:2019-05-24

本文共 8927 字,大约阅读时间需要 29 分钟。

二 .全文检索工具elasticsearch

1 . lucene与elasticsearch

咱们之前讲的处理分词,构建倒排索引,等等,都是这个叫lucene的做的。那么能不能说这个lucene就是搜索引擎呢?
还不能。lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来的应用。
好比lucene是类似于jdk,而搜索引擎软件就是tomcat 的。
目前市面上流行的搜索引擎软件,主流的就两款,elasticsearch和solr,这两款都是基于lucene的搭建的,可以独立部署启动的搜索引擎服务软件。由于内核相同,所以两者除了服务器安装、部署、管理、集群以外,对于数据的操作,修改、添加、保存、查询等等都十分类似。就好像都是支持sql语言的两种数据库软件。只要学会其中一个另一个很容易上手。
从实际企业使用情况来看,elasticSearch的市场份额逐步在取代solr,国内百度、京东、新浪都是基于elasticSearch实现的搜索功能。国外就更多了 像维基百科、GitHub、Stack Overflow等等也都是基于ES的

2 . elasticSearch的使用场景

1、为用户提供按关键字查询的全文搜索功能。
2、著名的ELK框架(ElasticSearch,Logstash,Kibana),实现企业海量日志的处理分析的解决方案。大数据领域的重要一份子。
3 . elasticSearch的安装
详见
4 . elasticsearch的基本概念
cluster 整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。
node 集群中的一个节点,一般只一个进程就是一个node
shard 分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。
index 相当于rdbms的database, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。
type 类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合。
document 类似于rdbms的 row、面向对象里的object
field 相当于字段、属性

5 . 利用kibana学习 elasticsearch restful api (DSL)

5.1 es中保存的数据结构

public class  Movie {
String id; String name; Double doubanScore; List
actorList;}public class Actor{
String id;String name;}

这两个对象如果放在关系型数据库保存,会被拆成2张表,但是elasticsearch是用一个json来表示一个document。

所以他保存到es中应该是:

{
“id”:”1”, “name”:”operation red sea”, “doubanScore”:”8.5”, “actorList”:[ {
“id”:”1”,”name”:”zhangyi”},{
“id”:”2”,”name”:”haiqing”},{
“id”:”3”,”name”:”zhanghanyu”}]}

5.2 对数据的操作

5.2.1 查看es中有哪些索引

GET /_cat/indices?v

es 中会默认存在一个名为.kibana的索引

表头的含义

health	green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)status	是否能使用index	索引名uuid	索引统一编号         pri	主节点几个rep	从节点几个docs.count	文档数docs.deleted	文档被删了多少store.size	整体占空间大小pri.store.size	主节点占

5.2.2 增加一个索引

PUT /movie_index

5.2.3 删除一个索引

ES 是不删除也不修改任何数据

DELETE /movie_index

5.2.4 新增文档

1、格式 PUT /index/type/id

PUT /movie_index/movie/1{
"id":1, "name":"operation red sea", "doubanScore":8.5, "actorList":[ {
"id":1,"name":"zhang yi"},{
"id":2,"name":"hai qing"},{
"id":3,"name":"zhang han yu"}]}PUT /movie_index/movie/2{
"id":2, "name":"operation meigong river", "doubanScore":8.0, "actorList":[ {
"id":3,"name":"zhang han yu"}]}PUT /movie_index/movie/3{
"id":3, "name":"incident red sea", "doubanScore":5.0, "actorList":[ {
"id":4,"name":"zhang chen"}]}

如果之前没建过index或者type,es 会自动创建。

5.2.5 直接用id查找

GET movie_index/movie/1

5.2.6 修改—整体替换

和新增没有区别

PUT /movie_index/movie/3{
"id":"3", "name":"incident red sea", "doubanScore":"5.0", "actorList":[ {
"id":"1","name":"zhang chen"}]}

5.2.7修改—某个字段

POST movie_index/movie/3/_update{
"doc": {
"doubanScore":"7.0" } }

5.2.8 删除一个document

DELETE movie_index/movie/3

5.2.9 搜索type全部数据

GET movie_index/movie/_search

结果

{
"took": 2, //耗费时间 毫秒 "timed_out": false, //是否超时 "_shards": {
"total": 5, //发送给全部5个分片 "successful": 5, "skipped": 0, "failed": 0 }, "hits": {
"total": 3, //命中3条数据 "max_score": 1, //最大评分 "hits": [ // 结果 {
"_index": "movie_index", "_type": "movie", "_id": 2, "_score": 1, "_source": {
"id": "2", "name": "operation meigong river", "doubanScore": 8.0, "actorList": [ {
"id": "1", "name": "zhang han yu" } ] } 。。。。。。。。 。。。。。。。。 }

5.2.10 按条件查询(全部)

GET movie_index/movie/_search{
"query":{
"match_all": {
} }}

5.2.11 按分词查询

GET movie_index/movie/_search{
"query":{
"match": {
"name":"red"} }}

注意结果的评分

5.2.12 按分词子属性查询

GET movie_index/movie/_search{
"query":{
"match": {
"actorList.name":"zhang"} }}

5.2.13 match phrase

GET movie_index/movie/_search{
"query":{
"match_phrase": {
"name":"operation red"} }}

按短语查询,不再利用分词技术,直接用短语在原始数据中匹配

5.2.14 fuzzy查询

GET movie_index/movie/_search{
"query":{
"fuzzy": {
"name":"rad"} }}

校正匹配分词,当一个单词都无法准确匹配,es通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。

5.2.15 过滤–查询后过滤

GET movie_index/movie/_search{
"query":{
"match": {
"name":"red"} }, "post_filter":{
"term": {
"actorList.id": 3 } }}

5.2.16 过滤–查询前过滤(推荐)

GET movie_index/movie/_search{
"query":{
"bool":{
"filter":[ {
"term": {
"actorList.id": "1" }}, {
"term": {
"actorList.id": "3" }} ], "must":{
"match":{
"name":"red"}} } }}

5.2.17 过滤–按范围过滤

GET movie_index/movie/_search{
"query": {
"bool": {
"filter": {
"range": {
"doubanScore": {
"gte": 8} } } } }}

关于范围操作符:

gt	大于lt	小于gte	大于等于lte	小于等于

5.2.18 排序

GET movie_index/movie/_search{
"query":{
"match": {
"name":"red sea"} } , "sort": [ {
"doubanScore": {
"order": "desc" } } ]}

5.2.19 分页查询

GET movie_index/movie/_search{
"query": {
"match_all": {
} }, "from": 1, "size": 1}

5.2.20 指定查询的字段

GET movie_index/movie/_search{
"query": {
"match_all": {
} }, "_source": ["name", "doubanScore"]}

5.2.21 高亮

GET movie_index/movie/_search{
"query":{
"match": {
"name":"red sea"} }, "highlight": {
"fields": {
"name":{
} } } }

自定义标签

GET movie_index/movie/_search{
"query":{
"match": {
"name":"red sea"} }, "highlight": {
"pre_tags": [""], "post_tags": [""], "fields": {
"name":{
} } } }

5.2.22 聚合

取出每个演员共参演了多少部电影

GET movie_index/movie/_search{
"aggs": {
"groupby_actor": {
"terms": {
"field": "actorList.name.keyword" } } }}

每个演员参演电影的平均分是多少,并按评分排序

GET movie_index/movie/_search{
"aggs": {
"groupby_actor_id": {
"terms": {
"field": "actorList.name.keyword" , "order": {
"avg_score": "desc" } }, "aggs": {
"avg_score":{
"avg": {
"field": "doubanScore" } } } } }}

5.3 关于mapping

之前说type可以理解为table,那每个字段的数据类型是如何定义的呢
查看看mapping

GET movie_index/_mapping/movie

实际上每个type中的字段是什么数据类型,由mapping定义。

但是如果没有设定mapping系统会自动,根据一条数据的格式来推断出应该的数据格式。

true/false → boolean1020  →  long20.1 → double“2018-02-01” → date“hello world” → text +keyword

默认只有text会进行分词,keyword是不会分词的字符串。

mapping除了自动定义,还可以手动定义,但是只能对新加的、没有数据的字段进行定义。一旦有了数据就无法再做修改了。
注意:虽然每个Field的数据放在不同的type下,但是同一个名字的Field在一个index下只能有一种mapping定义。

5.4 中文分词

elasticsearch本身自带的中文分词,就是单纯把中文一个字一个字的分开,根本没有词汇的概念。但是实际应用中,用户都是以词汇为条件,进行查询匹配的,如果能够把文章以词汇为单位切分开,那么与用户的查询条件能够更贴切的匹配上,查询速度也更加快速。
分词器下载网址:

5.4.1 安装

下载好的zip包,请解压后放到 /usr/share/elasticsearch/plugins/ik
在这里插入图片描述

然后重启es

5.4.2测试使用
使用默认

GET movie_index/_analyze{
"text": "我是中国人"}
请观察结果

使用分词器

GET movie_index/_analyze{
"analyzer": "ik_smart", "text": "我是中国人"}
请观察结果

另外一个分词器

ik_max_wordGET movie_index/_analyze{
"analyzer": "ik_max_word", "text": "我是中国人"}

请观察结果

能够看出不同的分词器,分词有明显的区别,所以以后定义一个type不能再使用默认的mapping了,要手工建立mapping, 因为要选择分词器。

5.4.3基于中文分词搭建索引

1、建立mapping

PUT movie_chn{
"mappings": {
"movie_type_chn":{
"properties": {
"id":{
"type": "long" }, "name":{
"type": "text" , "analyzer": "ik_smart" }, "doubanScore":{
"type": "double" }, "actorList":{
"properties": {
"id":{
"type":"long" }, "name":{
"type":"keyword" } } } } } }}

插入数据

PUT /movie_chn/movie_type_chn/1{
"id":1, "name":"红海行动", "doubanScore":8.5, "actorList":[ {
"id":1,"name":"张译"}, {
"id":2,"name":"海清"}, {
"id":3,"name":"张涵予"} ]}PUT /movie_chn/movie_type_chn/2{
"id":2, "name":"湄公河行动", "doubanScore":8.0, "actorList":[ {
"id":3,"name":"张涵予"}]}PUT /movie_chn/movie_type_chn/3{
"id":3, "name":"红海事件", "doubanScore":5.0, "actorList":[ {
"id":4,"name":"张晨"}]}

查询测试

GET /movie_chn/movie_type_chn/_search{
"query": {
"match": {
"name": "红海战役" } }}GET /movie_chn/movie_type_chn/_search{
"query": {
"term": {
"actorList.name": "张译" } }}

5.4.4 自定义词库

修改/usr/share/elasticsearch/plugins/ik/config/中的IKAnalyzer.cfg.xml

IK Analyzer 扩展配置
http://192.168.67.163/fenci/myword.txt

按照标红的路径利用nginx发布静态资源

在nginx.conf中配置

server {        listen  80;        server_name  192.168.67.163;        location /fenci/ {           root es;    }   }

并且在/usr/local/nginx/下建/es/fenci/目录,目录下加myword.txt

myword.txt中编写关键词,每一行代表一个词。

然后重启es服务器,重启nginx。

在kibana中测试分词效果

更新完成后,es只会对新增的数据用新词分词。历史数据是不会重新分词的。如果想要历史数据重新分词。需要执行:

POST movies_index_chn/_update_by_query?conflicts=proceed

转载地址:http://xuzki.baihongyu.com/

你可能感兴趣的文章
Flutter UI基础 - webview 使用和交互
查看>>
Flutter UI基础 - 时间选择器
查看>>
Idea - 创建Java类时,自动在文件头中添加作者和创建时间
查看>>
Docker - ASP.NET Core Docker部署
查看>>
Docker - 容器运行 .Net Core
查看>>
Django - TypeError: __init__() missing 1 required positional argument: ‘on_delete‘ 的解决办法
查看>>
Go - 解决 go get 超时问题
查看>>
Go - goose 数据库迁移工具
查看>>
SQL - SQL Server 之遍历数据集合的几种方法
查看>>
SQL - SQL Server 之处理JSON数据
查看>>
SQL - SQL Server 之ETL详解
查看>>
SQL - SQL Server 之Merge函数使用详解
查看>>
SQL - SQL Server 之WHILE循环的坑
查看>>
SQL - SQL Server中如何获取当前年,月,日,时,分,秒
查看>>
SQL - SQL Server 性能优化之SQL语句总结
查看>>
Docker - docker-compose常用命令
查看>>
SQL - SQL Server判断字符串中是否有中文
查看>>
SQL - SQL Server查询近7天的连续日期
查看>>
SQL - SQL Server中如何取年、月、日 -DATEPART函数
查看>>
SQL - SQL Server 一列或多列重复数据的查询,删除
查看>>