全文检索基础

全文检索流程

流程:

#mermaid-svg-7Eg2qFEl06PIEAxZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .error-icon{fill:#552222;}#mermaid-svg-7Eg2qFEl06PIEAxZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7Eg2qFEl06PIEAxZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .marker.cross{stroke:#333333;}#mermaid-svg-7Eg2qFEl06PIEAxZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7Eg2qFEl06PIEAxZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .cluster-label text{fill:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .cluster-label span{color:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .label text,#mermaid-svg-7Eg2qFEl06PIEAxZ span{fill:#333;color:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .node rect,#mermaid-svg-7Eg2qFEl06PIEAxZ .node circle,#mermaid-svg-7Eg2qFEl06PIEAxZ .node ellipse,#mermaid-svg-7Eg2qFEl06PIEAxZ .node polygon,#mermaid-svg-7Eg2qFEl06PIEAxZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7Eg2qFEl06PIEAxZ .node .label{text-align:center;}#mermaid-svg-7Eg2qFEl06PIEAxZ .node.clickable{cursor:pointer;}#mermaid-svg-7Eg2qFEl06PIEAxZ .arrowheadPath{fill:#333333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7Eg2qFEl06PIEAxZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-7Eg2qFEl06PIEAxZ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-7Eg2qFEl06PIEAxZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7Eg2qFEl06PIEAxZ .cluster text{fill:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ .cluster span{color:#333;}#mermaid-svg-7Eg2qFEl06PIEAxZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7Eg2qFEl06PIEAxZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

创建索引
返回结果
查询索引
原始文档
创建索引
索引库
查询索引

创建索引:

#mermaid-svg-IT3RG8yOe0uONXZD {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-IT3RG8yOe0uONXZD .error-icon{fill:#552222;}#mermaid-svg-IT3RG8yOe0uONXZD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IT3RG8yOe0uONXZD .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-IT3RG8yOe0uONXZD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IT3RG8yOe0uONXZD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IT3RG8yOe0uONXZD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IT3RG8yOe0uONXZD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IT3RG8yOe0uONXZD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IT3RG8yOe0uONXZD .marker.cross{stroke:#333333;}#mermaid-svg-IT3RG8yOe0uONXZD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IT3RG8yOe0uONXZD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IT3RG8yOe0uONXZD .cluster-label text{fill:#333;}#mermaid-svg-IT3RG8yOe0uONXZD .cluster-label span{color:#333;}#mermaid-svg-IT3RG8yOe0uONXZD .label text,#mermaid-svg-IT3RG8yOe0uONXZD span{fill:#333;color:#333;}#mermaid-svg-IT3RG8yOe0uONXZD .node rect,#mermaid-svg-IT3RG8yOe0uONXZD .node circle,#mermaid-svg-IT3RG8yOe0uONXZD .node ellipse,#mermaid-svg-IT3RG8yOe0uONXZD .node polygon,#mermaid-svg-IT3RG8yOe0uONXZD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IT3RG8yOe0uONXZD .node .label{text-align:center;}#mermaid-svg-IT3RG8yOe0uONXZD .node.clickable{cursor:pointer;}#mermaid-svg-IT3RG8yOe0uONXZD .arrowheadPath{fill:#333333;}#mermaid-svg-IT3RG8yOe0uONXZD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IT3RG8yOe0uONXZD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IT3RG8yOe0uONXZD .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-IT3RG8yOe0uONXZD .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-IT3RG8yOe0uONXZD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IT3RG8yOe0uONXZD .cluster text{fill:#333;}#mermaid-svg-IT3RG8yOe0uONXZD .cluster span{color:#333;}#mermaid-svg-IT3RG8yOe0uONXZD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IT3RG8yOe0uONXZD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

获取文档
构建文档对象
分析文档'分词'
创建索引

查询索引:

#mermaid-svg-fOlPsWU4MYPYMo85 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 .error-icon{fill:#552222;}#mermaid-svg-fOlPsWU4MYPYMo85 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fOlPsWU4MYPYMo85 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-fOlPsWU4MYPYMo85 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fOlPsWU4MYPYMo85 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fOlPsWU4MYPYMo85 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fOlPsWU4MYPYMo85 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fOlPsWU4MYPYMo85 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fOlPsWU4MYPYMo85 .marker.cross{stroke:#333333;}#mermaid-svg-fOlPsWU4MYPYMo85 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fOlPsWU4MYPYMo85 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 .cluster-label text{fill:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 .cluster-label span{color:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 .label text,#mermaid-svg-fOlPsWU4MYPYMo85 span{fill:#333;color:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 .node rect,#mermaid-svg-fOlPsWU4MYPYMo85 .node circle,#mermaid-svg-fOlPsWU4MYPYMo85 .node ellipse,#mermaid-svg-fOlPsWU4MYPYMo85 .node polygon,#mermaid-svg-fOlPsWU4MYPYMo85 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fOlPsWU4MYPYMo85 .node .label{text-align:center;}#mermaid-svg-fOlPsWU4MYPYMo85 .node.clickable{cursor:pointer;}#mermaid-svg-fOlPsWU4MYPYMo85 .arrowheadPath{fill:#333333;}#mermaid-svg-fOlPsWU4MYPYMo85 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fOlPsWU4MYPYMo85 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fOlPsWU4MYPYMo85 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-fOlPsWU4MYPYMo85 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-fOlPsWU4MYPYMo85 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fOlPsWU4MYPYMo85 .cluster text{fill:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 .cluster span{color:#333;}#mermaid-svg-fOlPsWU4MYPYMo85 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fOlPsWU4MYPYMo85 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

用户查询结构
创建查询
执行查询
渲染结果

相关概念

索引库

索引库就是存储索引的保存在磁盘上的一系列的文件。里面存储了建立好的索引消息以及文档对象。

** 一个索引库相当于数据库中的一张表,一个文档对象相当于数据库中的一行数据

doucument对象

获取原始内容的目的是为了索引,在索引前需要将原始内容建成文档,文档中包含一个一个的域(字段),域中存储内容。每个文档都有一个唯一的编号,就是文档id。

field对象

如果我们把document看作是数据库中的一条记录的话,field相当于是记录中的字段。field是索引库中存储数据的最小单位。field的数据类型大致可以分为数值类型和文本类型,一般需要查询的字段都是文本类型的,field还有如下属性:

是否分词:是否对域的内容进行分词处理。前提是我们对域的内容进行查询

是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到

是否存储:Field值存储在文档中,存储在文档中的Field才可以从Document中获取

term对象

从文档对象中拆分出来的每个单词叫做term,不同域中拆分出来的相同的单词是不同term。term中包含两部分,一部分是文档的域名。另一部分是单词的内容。term是创建索引的关键词对象。

ElasticSearch相关概念

概述

ES是面对文档的,这意味这它可以存储整个对象或文档。然而它不仅仅是存储,还会索引每个文档的内容使之可以被搜索。在ES中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。

ES比较传统关系型数据库如下:

Relational DB -> Databases->Tables->Rows ->Columns

ES->Indices->Types->Documents->Fields

ES核心概念

索引index

一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。

类型type

在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定,通常,会为具有一组共同字段文档定义一个类型。比如说,我们假设你运营一个博客平台

字段Field

相当于是字段表的字段,对文档数据根据不同属性进行的分类标识

映射mapping

mapping是处理数据的范式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其他就是处理es里面的数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。

文档document

一个文档是一个可被索引的基础消息单元。比如,你可以拥有某一个客户的文档,某个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON格式来表示,而JSON是一个到处存在的互联网数据交互格式

在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type

接近实时NRT

ES是一个接近实时的搜索平台,这意味这,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟

集群cluster

集群就是有一个或多个节点组织在一起,它们共同持有整个数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是es。这个名字是重要的,意味一个节点只能通过指定某个集群的名字来加入这个集群

节点node

一个节点是集群的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识,默认情况下,这个名字是一个随机的名字。

分片和复制 shards&replicas

一个索引可以存储超出单个节点硬件限制的大量数据。每个分片本身也是一个功能完善并且独立的索引,这个索引可以被放置到集群的任何节点上。分片很重要,主要有两方面:

1)允许你水平分割/扩展你的内容容量

2)允许你的分片(潜在地,位于多个节点上)之上进行分布式、并行的操作,进而提高性能/吞吐量

要复制的两个原因:在分片/节点失败的情况下,提高了高可用性。因为这个原因,主要到复制分片从不与原/主要分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量。因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片,一个索引也可以被复制0次或多次,一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你是不能改变分片的数量

安装

docker安装

sudo docker pull elasticsearch:5.6.8

启动

sudo docker run -id --name=zys_es -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8

注意:可能因为内存不够或者进程满等原因会中断es进程

安装包安装

sudo apt-get install openjdk-8-jdk #1、安装open-jdk
#2、官网查找需要的es版本 es官网:https://www.elastic.co/cn/downloads/elasticsearch
#点击【apt-get】
#查找自己想要的版本,点击使用deb方式安装
#安装es-7.6.2
1、wgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-amd64.deb
2、wgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-amd64.deb.sha512
3、shasum -a 512 -c elasticsearch-7.6.2-amd64.deb.sha512
4、sudo dpkg -i elasticsearch-7.6.2-amd64.deb
#修改配置文件elasticsearch.yml
vi /etc/elasticsearch/elasticsearch.yml{node.name: node-1
network.host: 0.0.0.0 #允许外网访问
http.port: 9200 #指定es端口号
clauster.initial_master_nodes: ["node-1"]
}
#修改jvm.options
{-Xms4g
-Xms4g
}
#启动es
sudo chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/  #目录的owner和group改成elasticsearch
systemctl enable elasticsearch.service    #设置es开机自启动
sudo systemctl start elasticsearch.service    #启动es
sudo systemctl stop elasticsearch.service    #停止es#查看es运行状态
service elasticsearch status
#查看报错日志
tail -f /var/log/elasticsearch/elasticsearch.log
#检查是否运行正常
curl localhost:9200# 开启跨域访问支持,默认为false
http.cors.enabled: true
# 跨域访问允许的域名地址
http.cors.allow-origin: "*"
# 通过为 cluster.initial_master_nodes 参数设置符合主节点条件的节点的 IP 地址来引导启动集群
cluster.initial_master_nodes: ["node-1"]

ElasticSearch的客户端操作

三种方式:

第一种:elasticsearch-head操作

第二种:使用elasticsearch提供的Restful接口直接访问

第三种:使用es提供的API直接访问

elasticsearch-head

下载elasticsearch-head安装包
进入目录下打开cmd
npm install -g grunt-cli
启动
npm install
grunt server

Postman

创建索引index和映射Mapping

注意:elasticsearch7默认不在支持指定索引类型,默认索引类型是_doc,如果想改变,则配置include_type_name: true 即可(这个没有测试,官方文档说的,无论是否可行,建议不要这么做,因为elasticsearch8后就不在提供该字段)。官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html

7.x之前:

{"settings":{    "number_of_shards" : 3,   "number_of_replicas" : 0    },    "mappings":{    "books":{     //指定索引"properties":{        "title":{"type":"text"},"name":{"type":"text","index":false}, //有index"publish_date":{"type":"date","index":false},           "price":{"type":"double"},           "number":{"type":"object","dynamic":true}}}}
}

7.x之后:

{"settings":{"number_of_shards":3, #分片数量"number_of_replicas":2 #每个分片副本},"mappings":{//无索引"properties":{"id":{"type":"long"},"name":{"type":"text","analyzer":"standard"}, //无指定index为true或为false,standard为分词器的一种,standard一个汉字一个词"text":{"type":"text","analyzer":"ik_max_word"}}}}

创建索引后设置Mapping

http://120.78.130.50:9200/blog7/hello/mapping{"properties":{"id":{"type":"long"},"name":{"type":"text","analyzer":"ik_smart"}, //无指定index为true或为false"text":{"type":"text","analyzer":"ik_max_word"}}}

创建文档document

请求url:

post http://120.78.130.50:9200/blog1/_doc/1

请求体:

{"id":1,"name":"es是一个lucene的搜索服务器", "text":"阿萨的贺卡收到萨拉DHL收到啦收到啦实打实的拉萨机的卡拉卡斯德拉夫拉上来就"
}

修改文档

请求url:

post http://120.78.130.50:9200/blog1/_doc/1

请求体:

{"id":1,"name":"es是一个lucene的搜索服务器反对犯得上", "text":"阿萨的贺卡收到萨拉DHL收到啦收到啦实打实的拉萨机的卡拉卡斯德拉夫拉上来就"
}

文档删除document

delete http://120.78.130.50:9200/blog1/_doc/1

根据id查询文档

GET http://120.78.130.50:9200/blog1/_doc/2

结果

{"_index": "blog1", //索引名称"_type": "_doc", //索引类型"_id": "2", "_version": 1,"_seq_no": 2,"_primary_term": 1,"found": true,"_source": { //数据"id": 1,"name": "es是一个lucene的搜索服务器", //无指定index为true或为false"text": "阿萨的贺卡收到萨拉DHL收到啦收到啦实打实的拉萨机的卡拉卡斯德拉夫拉上来就"}
}

查询文档-querystring查询

url:

POST http://120.78.130.50:9200/blog1/_doc/_search

请求体:

{"query": {"query_string": {"default_field": "name","query": "搜索服务器"}}
}

钢索->“钢”,“索”,搜索是分为两个词,注意Standard标准分词器,会把汉字每个字分为一个词存到索引库中的name,也就是按照Standard进行的分词,所以搜索钢索能搜到这个document

查询文档-term查询

url:

POST http://120.78.130.50:9200/blog1/_doc/_search

body

{"query": {"term": {"name": "搜索"}}
}

query_string :搜索之前对搜索的关键词分词

term:对搜索的关键词不分词

IK分词器

安装

下载安装包 :https://github.com/medcl/elasticsearch-analysis-ik/releases

放到/ usr/share/elasticsearch/plugins

重启es

7.x之前测试:

http://120.78.130.50:9200/_analyze?analyzer=ik_smart&pretty=true&text=我是程序员

http://120.78.130.50:9200/_analyze?analyzer=ik_max_word&pretty=true&text=我是程序员

7.x之后测试:url+body

http://120.78.130.50:9200/_analyze

{

“analyzer”: “ik_smart”,

“text”: “我是傻逼”

}

注意:

​ ik_smart:会做最粗粒度的拆分

​ ik_max_word: 会将文本做最细粒度的拆分

注意出错:将ik解压成功后es可能就启动不了,可能是ik中所有文件的用户组和所有者属于root,需要改成当前的用户组和所有者,用

sudo chmod zys_ergou ./ik/*

sudo chown zys_ergou ./ik/*

还有一种情况就是es和ik的版本不兼容,需要进入plugin-descriptor.properties文件更改es的version

Kibaba

安装

第一步:去官网下载Linux版本的Kibana

https://www.elastic.co/cn/downloads/past-releases#kibana

sudo wget https://artifacts.elastic.co/downloads/kibana/kibana-7.6.2-linux-x86_64.tar.gz

第二步:上传到Linux服务器(可能导致文件不完整,最好用wget下载)

第三步:解压该Kibana压缩包。

sudo tar -zxvf kibana-7.6.2-linux-x86_64.tar.gz //注意文件名称

第四步:去kibana目录下的config/kibana.yml配置相关参数。

  1. server.port: 5601
  2. server.host: “0.0.0.0”
  3. i18n.locale: “zh-CN”

第五步:启动Kibana。进入bin目录下

  1. #root账号启动
  2. ./kibana --allow-root
  3. #root账号后台启动
  4. nohup ./kibana --allow-root &
  5. #其他账号启动
  6. ./kibana
  7. #其他账号后台启动
  8. nohup ./kibana &

第六步:访问Kibana

http://192.168.120.157:5601/

第七步:访问Elasticsearch地址

快捷键:

ctrl + i 自动缩进

ctrl + enter 提交请求

down 打开自动补全菜单

enter 或tab 选中项自动补全

esc 关闭补全菜单

DSL语句使用

SQL查询语句

操作

(1)查询所有索引

GET /_cat/indices?v

(2)删除某个索引

DELETE /blog

(3)新增索引

PUT /user

(4)创建映射

注意:如果不设置include_type_name=true,就会报错"Types cannot be provided in put mapping requests, unless the include_type_name parameter is set to true."

PUT /user/uesrinfo/_mapping?include_type_name=true
{"properties": {"name":{"type": "text","analyzer": "ik_smart","search_analyzer": "ik_smart"},"city":{"type": "text","analyzer": "ik_smart","search_analyzer": "ik_smart"},"age":{"type": "long"},"description":{"type": "text","analyzer": "ik_smart","search_analyzer": "ik_smart"}}
}

(5)新增文档数据

PUT /user/_doc/{id}
{"name":"王五","age":21,"city":"广州","description":"王五来自湖北武汉"
}

(6)替换操作

PUT /user/_doc/3
{"name":"王五","age":21,"city":"广州","description":"王五来自湖北武汉"
}

(7)根据id查询

GET /user/_doc/2

(8)查询所有

GET /user/_search

(9)Sort排序

GET /user/_search
{"query": {"match_all": {}},"sort": [{"age": {"order": "desc"}}]
}

(10)分页

GET /user/_search
{"query": {"match_all": {}},"sort": [{"age": {"order": "desc"}}],"from": 0, "size": 2
}

(11)term查询

term主要用于分词精确匹配,如字符串、数值、日期等(不适合情况:1、列中除英文字符外有其他值2、字符串值中有冒号或中文3、系统自带属性如_version)

GET _search
{"query": {"term": {//term不分词"city": "深圳武汉"}}}
}GET _search
{"query": {"match": {//match分词"city": "深圳武汉"}}
}

(12)terms查询

terms查询允许指定多个匹配条件。如果某个字段指定了多个值,那么文档需要一起做匹配

GET _search
{"query": {"terms": {"city": ["武汉","广州"]}}
}

(13)query_string查询

GET _search
{"query": {"query_string": {"default_field": "city","query": "广州武汉"}}
}

(14)range查询

GET _search
{"query": {"range": {"age": {"gte": 20,"lte": 22}}}
}

(15)exists

exists过滤可以用于查找拥有某个域的数据

GET _search
{"query": {"exists": {"field": "address"}}
}

(16)bool查询

bool可以用来合并多个条件查询结果的布尔逻辑,它包含以下操作符:

must:多个查询条件的完全匹配,相当于and

must_not:多个查询条件的相反匹配,相当于not

should:至少有一个查询条件匹配,相当于or

这些参数可以分别继承一个过滤条件或者一个过滤条件的数组:

GET _search
{"query": {"bool": {"must": [{"term": {"city": {"value": "广州"}}},{"range": {"age": {"gte": 20,"lte": 22}}}]}}
}

(17)match_all查询

可以查询到所有文档,是没有查询条件下的默认句

GET /user/_search
{"query": {"match_all": {}}
}

(18)match查询

match查询是一个标准查询,不管你需要全文查询还是精确查询基本上都要用到它。如果你使用match查询一个全文本字段,它会在真正查询之前用飞行器先分析match一下查询字符:

GET _search
{"query": {"match": {"city": "广州"}}
}

(19)prefix查询

以什么字符开头的,可以更简单地用prefix,例如查询所有以张开始的用户描述

GET _search
{"query": {"prefix": {"name": {"value": "王"}}}
}

(20)multi_match

multi_match查询允许你做match查询的基础上同时搜索多个字段,在多个字段中同时查一个

GET _search
{"query": {"multi_match": {"query": "深圳","fields": ["city","description"]}}
}

ElasticSearch编程操作

添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zys</groupId><artifactId>es_demon</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.21</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-to-slf4j</artifactId><version>2.9.1</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>transport</artifactId><version>7.6.2</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.6.2</version></dependency></dependencies>
</project>

创建索引

         //1、配置
Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();//2、客户端TransportClient client = new PreBuiltTransportClient(settings);client.addTransportAddress(new TransportAddress(InetAddress.getByName("120.78.130.50"), 9300));//3、使用api创建索引client.admin().indices().prepareCreate("index_hello").get();//4、关闭clientclient.close();

添加映射

 //1、配置Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();//2、客户端TransportClient client = new PreBuiltTransportClient(settings);client.addTransportAddress(new TransportAddress(InetAddress.getByName("120.78.130.50"), 9300));XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("article").startObject("properties").startObject("id").field("type", "long").endObject().startObject("title").field("type", "text").field("analyzer", "ik_smart").endObject().startObject("content").field("type", "text").field("analyzer", "ik_smart").endObject().endObject().endObject().endObject();//3、使用api创建索引client.admin().indices().preparePutMapping("index_hello").setType("article").setSource(xContentBuilder).get();//4、关闭clientclient.close();

创建文档

1、使用XContenBuilder构建Document对象

XContentBuilder builder = XContentFactory.jsonBuilder().startObject().field("id", 2l).field("title", "少大金欧涉及到山东哈收到拉萨DHL撒鲁大师鲁大师劳动力").field("content", "啥的拉升阶段拉萨伦敦苏富比老大就是领导破碎了就爱上了大家来打死你电脑来合肥把程序内存,整理骄傲我觉得阿拉善的距离撒娇的了就").endObject();client.prepareIndex()//设置索引名称.setIndex("index_hello")//设置type.setType("article")//设置文档的id,如果不设置的话自动生成一个id.setId("1")//设置文档信息.setSource(builder)//执行操作.get();

2、实体对象

依赖:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.8.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.8.1</version></dependency>

实体类:

 private Integer id;private String title;private String content;

添加:

 Article article = new Article();article.setId(3l);article.setTitle("撒娇多久啊老师的就爱上了你发到你爱丽丝的你拉车的你");article.setContent("jdaosdnasdnlddawhlcncsnskndaskndasldnslnslkdsal;dasmd;");ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(article);client.prepareIndex().setIndex("index_hello").setType("article").setSource(objectMapper, XContentType.JSON).get();}

查询文档

TermQuery

 //创建QueryBuilder对象
//        QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "你");//term查询QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("你的宝贝").defaultField("title");//match查询
//        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "你的宝贝");//match查询
//        IdsQueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("3", "4");//根据id查询//执行查询得到一个结果SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder).get();//处理结果SearchHits hits = searchResponse.getHits();System.out.println("总行数" + hits.getTotalHits());Iterator<SearchHit> iterator = hits.iterator();while (iterator.hasNext()) {SearchHit next = iterator.next();//文档的json输入System.out.println(next.getSourceAsString());}

分页查询

//创建QueryBuilder对象MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "你的宝贝");//match查询//执行查询得到一个结果SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder).setFrom(0)///.setSize(5)///.get();//处理结果SearchHits hits = searchResponse.getHits();System.out.println("总行数" + hits.getTotalHits());Iterator<SearchHit> iterator = hits.iterator();while (iterator.hasNext()) {SearchHit next = iterator.next();//文档的json输入System.out.println(next.getSourceAsString());}

查询结果高亮显示

       MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("少啥", "title", "content");//multi_match查询
//HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("title");highlightBuilder.preTags("<em>");highlightBuilder.preTags("</em>");
///执行查询得到一个结果SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(queryBuilder).highlighter(highlightBuilder)//.get();//处理结果SearchHits hits = searchResponse.getHits();System.out.println("总行数" + hits.getTotalHits());Iterator<SearchHit> iterator = hits.iterator();while (iterator.hasNext()) {SearchHit next = iterator.next();//文档的json输入System.out.println(next.getSourceAsString()); System.out.println("==============highlight==============");Map<String, HighlightField> highlightFieldMap = next.getHighlightFields();for (Map.Entry<String, HighlightField> entry : highlightFieldMap.entrySet()) {System.out.println(entry.getKey() + "\t" + Arrays.toString( entry.getValue().getFragments()));}}

Spring Data ElasticSearch

1、搭建spring boot项目

Spring Data Release Train Spring Data Elasticsearch Elasticsearch Spring Framework Spring Boot
2022.0 (Turing) 5.0.x 8.5.0 6.0.x 3.0.x
2021.2 (Raj) 4.4.x 7.17.3 5.3.x 2.7.x
2021.1 (Q) 4.3.x 7.15.2 5.3.x 2.6.x
2021.0 (Pascal) 4.2.x[1] 7.12.0 5.3.x 2.5.x
2020.0 (Ockham)[1] 4.1.x[1] 7.9.3 5.3.2 2.4.x
Neumann[1] 4.0.x[1] 7.6.2 5.2.12 2.3.x
Moore[1] 3.2.x[1] 6.8.12 5.2.12 2.2.x
Lovelace[1] 3.1.x[1] 6.2.2 5.1.19 2.1.x
Kay[1] 3.0.x[1] 5.5.0 5.0.13 2.0.x
Ingalls[1] 2.1.x[1] 2.4.0 4.3.25 1.5.x

2、编写yml文件

spring:elasticsearch:rest:uris: 120.78.130.50:9300

3、编写实体类

//type在2.3.x版本不写即可,实体类名字即是type
@Document(indexName = "zys_blog", type = "article")
public class Article {@Id@Field(type = FieldType.Long, store = true)private Long id;@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")private String title;@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")private String content;
}

4、编写Dao

方法命名规则查询的基本语法findBy+属性+关键词+连接符

关键词:and,or,is,not,between,lessThanEqual

public interface ArticleDao extends ElasticsearchRepository<Article, Long> {}

5、使用

  @Autowiredprivate ElasticsearchRestTemplate template ;

RestHighLevelClient

引入依赖

 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency>
private RestHighLevelClient client;
@Testpublic void createIndex() throws IOException {HttpHost httpHost = HttpHost.create("120.78.130.50:9200");RestClientBuilder builder = RestClient.builder(httpHost);client = new RestHighLevelClient(builder);//创建连接CreateIndexRequest request = new CreateIndexRequest("book_index");String json = "{\n" +"  \"mappings\": {\n" +"    \"properties\": {\n" +"      \"id\":{\n" +"        \"type\":\"keyword\"\n" +"      },\n" +"      \"name\":{\n" +"        \"type\":\"text\",\n" +"        \"analyzer\":\"ik_max_word\"\n" +"      },\n" +"      \"type\":{\n" +"        \"type\":\"keyword\"\n" +"      },\n" +"      \"description\":{\n" +"        \"type\":\"text\",\n" +"        \"analyzer\": \"ik_max_word\"\n" +"      }\n" +"    }\n" +"  }\n" +"}";request.source(json, XContentType.JSON);client.indices().create(request, RequestOptions.DEFAULT);//创建索引库client.close();}

添加文档

@Testpublic void addDoc() throws Exception{Book book = bookDao.selectById(1);//从数据库中查询一个对象IndexRequest request = new IndexRequest("book_index").id(book.getId().toString());String json = JSON.toJSONString(book);//对象转为jsonrequest.source(json, XContentType.JSON);client.index(request, RequestOptions.DEFAULT);}//批处理添加文档//
@Testpublic void addallDoc() throws Exception{List<Book> bookList = bookDao.selectList(null);//从数据库中查询所有对象BulkRequest bulk = new BulkRequest();//创建一个批处理对象for (Book book : bookList) {IndexRequest request = new IndexRequest("book_index").id(book.getId().toString());String json = JSON.toJSONString(book);//对象转为jsonrequest.source(json, XContentType.JSON);bulk.add(request);}client.bulk(bulk, RequestOptions.DEFAULT);}

查询文档

///根据id查询
@Testvoid testQuery() throws IOException {GetRequest request = new GetRequest("book_index","1");GetResponse res = client.get(request, RequestOptions.DEFAULT);String sourceAsString = res.getSourceAsString();System.out.println(sourceAsString);}///条件查询/@Testvoid Query() throws IOException {SearchRequest request = new SearchRequest("book_index");//设置条件SearchSourceBuilder buider = new SearchSourceBuilder();buider.query(QueryBuilders.termQuery("name", "java"));request.source(buider);SearchResponse search = client.search(request, RequestOptions.DEFAULT);//处理结果SearchHits hits = search.getHits();for (SearchHit hit : hits) {String sourceAsString = hit.getSourceAsString();JSON.parseObject(sourceAsString, Book.class);//json对为对象System.out.println(Book);}}

聚合查询

划分桶:把不同标题分开

GET /car_index/car/_search
{"query": { //查询所有"bool": {"should": [{"match_all": {}}]}},"aggs": {"group_by_bland": { //group_by_bland为桶名字"terms": { //"field": "color", //把各颜色分开,比如白色为一组(一个容器aggregations),黄色为一组}}}
}

桶内度量

GET /car_index/car/_search
{"query": {"bool": {"should": [{"match_all": {}}]}},"aggs": {"group_by_bland": {"terms": {"field": "color" //分开各颜色},"aggs": {"avg_price": {"avg": {"field": "price" //求各颜色里面的价格平均值}}}}}
}

ElasticSearch搜索详细讲解与操作相关推荐

  1. Elasticsearch的详细讲解

    认识Elasticsearch是什么 Elasticsearch是一个搜索引擎 , 其本质就是一个非关系性数据库 什么是搜索引擎 所谓搜索引擎就是根据用户需求与一定的算法 , 运用特定的策略从互联网检 ...

  2. Elasticsearch搜索类型讲解(QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH)...

    es在查询时,可以指定搜索类型为QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH.那么这4种搜索 ...

  3. PHP 操作redis 详细讲解

    2019独角兽企业重金招聘Python工程师标准>>> Redis 菜鸟教程学习网址 http://www.runoob.com/redis/redis-install.html 挺 ...

  4. 详细描述一下Elasticsearch搜索的过程

    详细描述一下Elasticsearch搜索的过程 我们都知道es是一个分布式的存储和检索系统,在存储的时候默认是根据每条记录的_id字段做路由分发的,这意味着es服务端是准确知道每个document分 ...

  5. SQL中数据定义语言和数据操作语言的详细讲解

    我前面一篇博客讲解了什么是数据库中数据的定义语言和操作语言,接下来我们就详细讲解下 首先是数据的定义语言 1.CREATE DATABASE 语句 CREATE DATABASE 用于创建数据库. S ...

  6. Server操作Mxd文件详细讲解

    Server操作Mxd文件详细讲解 Server发布地图都是基于Mxd去发布的,这点与IMS使用axl文件差不多.一般来说,发布后mxd尽可能不要修改,或者在通过使用arcMap进行编辑后在重新发布. ...

  7. ELK Stack 日志分析 Elasticsearch搜索权限

    视频下载地址:链接:http://pan.baidu.com/s/1qYrgyPe 密码:s9sr 这几年国内运维都在不断完善运维自动化! 设想,IT运维自动化建设完成之后,那下一步怎么走? 我可以很 ...

  8. JAVA商城项目(微服务框架)——第11天 elasticsearch搜索

    0.学习目标 独立安装Elasticsearch 会使用Rest的API操作索引 会使用Rest的API查询数据 会使用Rest的API聚合数据 掌握Spring Data Elasticsearch ...

  9. 【云原生】Docker仓库详细讲解,搭建使用 Docker Registry 私服

    前言 大家好,本文是对 Docker 仓库的详细讲解,讲解了如何使用官方仓库,在官方仓库搜寻镜像,以及搭建 Docker Registry 私服.希望对大家有所帮助~ 目录 前言 一.访问 Docke ...

最新文章

  1. 递归和迭代的区别是什么,各有什么优缺点?
  2. Java总结:SpringBoot的使用cmd命令进行Gradle构建
  3. CentOS7/RHEL7编译安装Python3.6(支持SSL)
  4. IDM下载百度资源出现403的解决方法
  5. extjs引入html,ExtJs教程第一集 搭建ext环境后的第一个hello World
  6. espeak 开源离线语音合成工具
  7. C语言输入10名同学3门课,输入10个学生3门课的成绩,统计各科全部及格的人数(c语音)...
  8. Excel VBA打开IE浏览器的网页
  9. 观察者模式-百度摇号短信提醒举例说明
  10. 一名合格的大数据测试工程师,需要掌握哪些基本知识
  11. Android学习之登陆界面设计(二)基本界面设计
  12. diy nas配置推荐2019_打造家用NAS之一(2019年版)
  13. 【Linux 内核】编译 Linux 内核 ⑦ ( 安装内核模块 | 安装内核 | 重启系统 | 查看当前内核版本 )
  14. 通过fsockopen()方法从中国福彩网获取双色球历史中奖数据
  15. 【流媒体服务器Mediasoup】环境部署与demo搭建(二)
  16. 阿里云OSS上传下载和短信验证码
  17. 一个完整的URL地址包含什么
  18. Windows 2003 安全优化设置大全
  19. 将Pycharm中调整字体大小的方式设置为“ctrl+鼠标滚轮上下滑”
  20. HTML5+CSS网页设计作业——传统节日-春节(8页) 学生网站模板

热门文章

  1. 备战面试日记(3.2) - (设计模式.23种设计模式之创建型模式)
  2. 华为鸿蒙战略发布会内容,万物互联!华为鸿蒙发布会带来无限可能
  3. 2019BNUZ_ACM国庆欢乐赛题解
  4. 算法设计与分析——第五章回溯法 批处理作业调度 + 最大团问题+图的m着色问题
  5. 有一种蓝叫 APEC 蓝
  6. 人工智能既预测世界杯冠军,还帮你“讨债”?
  7. 航空Ethernet嵌入式测试平台ETest
  8. Win10如何开启并新建虚拟机?
  9. 三坐标检测基础知识之建立工件坐标系
  10. 二手苹果手机哪个性价比高?