ElasticSearch的客户端操作
官方文档地址: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
实际开发中,有多种方式操作Elasticsearch:
客户端工具:发送http请求(RESTful风格)操作:9200端口
使用Postman发送请求直接操作
使用ElasticSearch-head-master图形化界面插件操作
使用Elastic官方数据可视化的平台Kibana进行操作【推荐】
Java代码操作:9300端口
Elasticsearch提供的Java API 客户端进行操作
Spring Data ElasticSearch 持久层框架进行操作
官网支持的客户端访问方式:
https://www.elastic.co/guide/en/elasticsearch/client/index.html
使用Kibana进行以下实验,进行Restful接口访问
索引库操作,完成对索引的增、删、查操作
发送请求:
# 在kibana中,不用写地址和端口,/shopping是简化写法,真实请求地址是:http://127.0.0.1:9200/shopping
# 请求方法:PUT
PUT /shopping
响应结果:
#! Deprecation: the default number of shards will change from [5] to [1] in 7.0.0; if you wish to continue using the default of [5] shards, you must manage this on the create index request or with an index template
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "shopping"
}
“acknowledged” : true, 代表操作成功
“shards_acknowledged” : true, 代表分片操作成功
“index” : “shopping” 表示创建的索引库名称
注意:创建索引库的分片数默认5片,在7.0.0之后的ElasticSearch版本中,默认1片;
发送请求:
# 请求方法:GET
GET /_cat/indices?v
表头的含义(查看帮助信息:GET /_cat/indices?help)
health 当前服务器健康状态:
green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status 索引打开、关闭状态
index 索引名
uuid 索引统一编号
pri 主分片数量
rep 副分片数量
docs.count 可用文档数量
docs.deleted 文档删除状态(逻辑删除,段合并时被清理)
store.size 主分片和副分片整体占空间大小
pri.store.size 主分片占空间大小
发送请求:
# 请求方法:GET
GET /shopping
响应结果:
{
"shopping" : {
"aliases" : { },
"mappings" : { },
"settings" : {
"index" : {
"creation_date" : "1586587411462",
"number_of_shards" : "5",
"number_of_replicas" : "1",
"uuid" : "VCl1hHsJQDe2p2dn46o0NA",
"version" : {
"created" : "6080199"
},
"provided_name" : "shopping"
}
}
}
}
内容解释:
{
"shopping【索引库名】" : {
"aliases【别名】" : { },
"mappings【映射】" : { },
"settings"【索引库设置】 : {
"index【索引】" : {
"creation_date【创建时间】" : "1586587411462",
"number_of_shards【索引库分片数】" : "5",
"number_of_replicas【索引库副本数】" : "1",
"uuid【唯一标识】" : "VCl1hHsJQDe2p2dn46o0NA",
"version【版本】" : {
"created" : "6080199"
},
"provided_name【索引库名称】" : "shopping"
}
}
}
}
发送请求:
# 请求方法:DELETE
DELETE /shopping
响应结果:
{
"acknowledged" : true
}
类型(type)及(mapping)操作
有了索引库,等于有了数据库中的database。
接下来就需要建索引库(index)中的类型(type)了,类似于数据库(database)中的表(table)。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,在创建索引库的类型时,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。
给shopping这个索引库添加了一个名为product的类型,并且在类型中设置了4个字段:
title:商品标题
subtitle: 商品子标题
images:商品图片
price:商品价格
发送请求:
# 请求方法:PUT
PUT /shopping/product/_mapping
{
"properties": {
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"subtitle":{
"type": "text",
"analyzer": "ik_max_word"
},
"images":{
"type": "keyword",
"index": false
},
"price":{
"type": "float",
"index": true
}
}
} PUT /索引库名/_mapping/类型名称 或 索引库名/类型名称/_mapping
{
"properties": {
"字段名称":{
"type【类型】": "类型",
"index【是否索引】": true,
"store【是否存储】": false,
"analyzer【分词器】": "具体分词器"
}
...
}
}
响应结果:
#! Deprecation: [types removal] Specifying types in put mapping requests is deprecated. To be compatible with 7.0, the mapping definition should not be nested under the type name, and the parameter include_type_name must be provided and set to false.
{
"acknowledged" : true
}
说明:
#! 弃用:[类型删除]不建议在放置映射请求中指定类型。 为了与7.0兼容,映射定义不应嵌套在类型名称下,并且必须提供参数include_type_name并将其设置为false。
类型名称:就是前面将的type的概念,类似于数据库中的表
字段名:任意填写,下面指定许多属性,例如:title、subtitle、images、price
type:类型,Elasticsearch中支持的数据类型非常丰富,说几个关键的:
①String类型,又分两种:
text:可分词
keyword:不可分词,数据会作为完整字段进行匹配
②Numerical:数值类型,分两类
基本数据类型:long、interger、short、byte、double、float、half_float
浮点数的高精度类型:scaled_float
③Date:日期类型
④Array:数组类型
⑤Object:对象
index:是否索引,默认为true,也就是说你不进行任何配置,所有字段都会被索引。
true:字段会被索引,则可以用来进行搜索
false:字段不会被索引,不能用来搜索
store:是否将数据进行独立存储,默认为false
原始的文本会存储在_source里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true即可,获取独立存储的字段要比从_source中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。
analyzer:分词器,这里的ik_max_word即使用ik分词器
发送请求:
# 请求方法:GET
GET /shopping/product/_mapping
响应结果:
{
"shopping" : {
"mappings" : {
"product" : {
"properties" : {
"images" : {
"type" : "keyword",
"index" : false
},
"price" : {
"type" : "float"
},
"subtitle" : {
"type" : "text",
"analyzer" : "ik_max_word"
},
"title" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
}
3. 创建索引库同时进行映射配置(常用)
发送请求:
# 请求方法:PUT
PUT /shopping2
{
"settings": {},
"mappings": {
"product":{
"properties": {
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"subtitle":{
"type": "text",
"analyzer": "ik_max_word"
},
"images":{
"type": "keyword",
"index": false
},
"price":{
"type": "float",
"index": true
}
}
}
}
}
响应结果:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "shopping2"
}
发送请求:
# 请求方法:POST
POST /shopping/product
{
"title":"小米手机",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
响应结果:
{
"_index" : "shopping",
"_type" : "product",
"_id" : "indGaHEB1ahbZ0SRrXt3",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
响应结果解释:
{
"_index【索引库】" : "shopping",
"_type【类型】" : "product",
"_id【主键id】" : "indGaHEB1ahbZ0SRrXt3",
"_version【版本】" : 1,
"result【操作结果】" : "created",
"_shards【分片】" : {
"total【总数】" : 2,
"successful【成功】" : 1,
"failed【失败】" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
可以看到结果显示为:created
,是创建成功了。
另外,需要注意的是,在响应结果中有个_id
字段,这个就是这条文档数据的唯一标识
,以后的增删改查都依赖这个id作为唯一标示。可以看到id的值为:indGaHEB1ahbZ0SRrXt3,这里我们新增时没有指定id,所以是ES帮我们随机生成的id。
多创建几条数据:
POST /shopping/product/2
{
"title":"华为手机",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4999.00
}
POST /shopping/product/3
{
"title":"小米电视",
"images":"http://www.gulixueyuan.com/xmds.jpg",
"price":5999.00
}
发送请求:
# 请求方法:GET
GET /shopping/product/indGaHEB1ahbZ0SRrXt3
响应结果:
{
"_index" : "shopping",
"_type" : "product",
"_id" : "indGaHEB1ahbZ0SRrXt3",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
}
响应结果解释:
{
"_index【索引库】" : "shopping",
"_type【类型】" : "product",
"_id【主键id】" : "indGaHEB1ahbZ0SRrXt3",
"_version【版本】" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found【查询结果】" : true,
"_source【源文档信息】" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
}
• _source:源文档信息,所有的数据都在里面。
• _id:这条文档的唯一标示
• found:查询结果,返回true代表查到,false代表没有
发送请求:
# 请求方法:POST
POST /shopping/product/1
{
"title":"小米手机",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
响应结果:
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
• 主键id变为指定的id
请求url不变,请求体变化,会将原有数据内容覆盖。
发送请求:
# 请求方法:POST
POST /shopping/product/1
{
"title":"华为手机",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4999.00
}
响应结果:
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
可以看到result结果是:updated,使用GET /shopping/product/1查询,发现数据被更新。
发送请求:
# 请求方法:POST
POST /shopping/product/1/_update
{
"doc": {
"price":3000.00
}
}
响应结果:
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 1
}
可以看到result结果是:updated,使用GET /shopping/product/1查询,发现数据被更新。
删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。
Elasticsearch会在段合并时(磁盘碎片整理)进行删除内容的清理。
发送请求:
# 请求方法:DELETE
DELETE /shopping/product/1
响应结果:
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_version" : 3,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1
}
可以看到result结果是:deleted,数据被删除。如果删除不存在的文档,result:not_found
例如:
DELETE /shopping/product/11主键不存在
{
"_index" : "shopping",
"_type" : "product",
"_id" : "11",
"_version" : 1,
"result" : "not_found",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
发送请求:
# 请求方法:DELETE
POST /shopping/_delete_by_query
{
"query":{
"match":{
"title":"手机"
}
}
}
响应结果:
{
"took" : 33,
"timed_out" : false,
"total" : 2,
"deleted" : 2,
"batches" : 1,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"failures" : [ ]
}
响应结果解释:
{
"took【耗时】" : 33,
"timed_out【是否超时】" : false,
"total【总数】" : 2,
"deleted【删除总数】" : 2,
"batches" : 1,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"failures" : [ ]
}
1. 请求体查询
Elasticsearch基于JSON提供完整的查询DSL来定义查询。
DSL(Domain Specific Language):领域特定语言
2. 基础数据
POST /shopping/product/1
{
"title":"小米手机",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
POST /shopping/product/2
{
"title":"华为手机",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4999.00
}
POST /shopping/product/3
{
"title":"小米电视",
"images":"http://www.gulixueyuan.com/xmds.jpg",
"price":5999.00
}
1) 查询所有(match_all)
发送请求:
# 请求方法:GET
#请求地址:http://127.0.0.1:9200/索引库名/_search
GET /shopping/_search
{
"query": {
"match_all": {}
}
}
请求解释:
GET /{索引库}/_search
{
"query":{
"查询类型":{
"查询条件":"查询条件值"
}
}
}
"query":这里的query代表一个查询对象,里面可以有不同的查询属性
"查询类型":例如:match_all(代表查询所有), match,term , range 等等
"查询条件":查询条件会根据类型的不同,写法也有差异
响应结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "华为手机",
"images" : "http://www.gulixueyuan.com/hw.jpg",
"price" : 4999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
}
}
]
}
}
响应结果解释:
{
"took【查询花费时间,单位毫秒】" : 1,
"timed_out【是否超时】" : false,
"_shards【分片信息】" : {
"total【总数】" : 5,
"successful【成功】" : 5,
"skipped【忽略】" : 0,
"failed【失败】" : 0
},
"hits【搜索命中结果】" : {
"total【命中总数】" : 3,
"max_score【所有查询结果中,文档的最高得分】" : 1.0,
"hits【命中结果集合】" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "华为手机",
"images" : "http://www.gulixueyuan.com/hw.jpg",
"price" : 4999.0
}
},
。。。
}
]
}
}
2) 匹配查询(match)
match类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"match": {
"title": "小米手机"
}
}
}
响应结果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "2",
"_score" : 0.2876821,
"_source" : {
"title" : "华为手机",
"images" : "http://www.gulixueyuan.com/hw.jpg",
"price" : 4999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 0.2876821,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
}
}
]
}
}
在上面的案例中,不仅会查询到电视,而且与小米相关的都会查询到。
某些情况下,我们需要更精确查找,我们希望这个关系变成and,可以这样做:
发送请求:
本例中,只有同时包含小米和手机的词条才会被搜索到。
GET /shopping/_search
{
"query": {
"match": {
"title": {
"query": "小米手机",
"operator": "and"
}
}
}
}
响应结果:
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
}
]
}
}
3) 多字段匹配查询(multi_match)
multi_match与match类似,不同的是它可以在多个字段中查询。
发送请求:
# 请求方法:GET
#fields属性:设置查询的多个字段名称
GET /shopping/_search
{
"query": {
"multi_match": {
"query": "小米",
"fields": ["title","subtitle"]
}
}
}
响应结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 0.2876821,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
}
}
]
}
}
4) 关键词精确查询(term)
term查询,精确的关键词匹配查询,不对查询条件进行分词。
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"term": {
"title": {
"value": "小米"
}
}
}
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 0.2876821,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
}
}
]
}
}
5) 多关键词精确查询(terms)
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。
如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于mysql的in
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"terms": {
"price": [3999,5999]
}
}
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
}
}
]
}
}
1. 指定查询字段
默认情况下,ElasticSearch在搜索的结果中,会把文档中保存在_source的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加_source的过滤
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"_source": ["title","price"],
"query": {
"terms": {
"price": [3999]
}
}
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"price" : 3999.0,
"title" : "小米手机"
}
}
]
}
}
2. 过滤指定字段:includes和excludes
我们也可以通过:
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
二者都是可选的。
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"_source": {
"includes": ["title","price"]
},
"query": {
"terms": {
"price": [3999]
}
}
}
GET /shopping/_search
{
"_source": {
"excludes": ["images"]
},
"query": {
"terms": {
"price": [3999]
}
}
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"price" : 3999.0,
"title" : "小米手机"
}
}
]
}
}
1. 布尔组合(bool)
bool
把各种其它查询通过must
(必须 )、must_not
(必须不)、should
(应该)的方式进行组合
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "小米"
}
}
],
"must_not": [
{
"match": {
"title": "电视"
}
}
],
"should": [
{
"match": {
"title": "手机"
}
}
]
}
}
}
响应结果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
}
]
}
}
2. 范围查询(range)
range 查询找出那些落在指定区间内的数字或者时间。range查询允许以下字符:
操作符 说明
gt == (greater than) 大于>
gte == (greater than equal) 大于等于>=
lt == (less than) 小于<
lte == (less than equal) 小于等于<=
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"range": {
"price": {
"gte": 2500,
"lte": 4000
}
}
}
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
}
}
]
}
}
3. 模糊查询(fuzzy)
返回包含与搜索字词相似的字词的文档。
编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
更改字符(box → fox)
删除字符(black → lack)
插入字符(sic → sick)
转置两个相邻字符(act → cat)
为了找到相似的术语,fuzzy查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。然后查询返回每个扩展的完全匹配。
通过fuzziness修改编辑距离。一般使用默认值AUTO,根据术语的长度生成编辑距离。
0…2
必须完全匹配
3…5
允许一次编辑
5
允许进行两次编辑
POST /shopping/product/4
{
"title":"apple手机",
"images":"http://www.gulixueyuan.com/apple.jpg",
"price":5999.00
}
POST /shopping/product/5
{
"title":"apple",
"images":"http://www.gulixueyuan.com/apple.jpg",
"price":4999.00
}
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"fuzzy": {
"title": {
"value": "ccple"
}
}
}
} GET /shopping/_search
{
"query": {
"fuzzy": {
"title": {
"value": "ccple",
"fuzziness": 2
}
}
}
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
} {
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.41588834,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "4",
"_score" : 0.41588834,
"_source" : {
"title" : "apple手机",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 5999.0
}
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "5",
"_score" : 0.17260925,
"_source" : {
"title" : "apple",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 4999.0
}
}
]
}
}
1. 单字段排序
sort 可以让我们按照不同的字段进行排序,并且通过order指定排序的方式。desc降序,asc升序。
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
响应结果:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : null,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "4",
"_score" : null,
"_source" : {
"title" : "apple手机",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 5999.0
},
"sort" : [
5999.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : null,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
},
"sort" : [
5999.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "5",
"_score" : null,
"_source" : {
"title" : "apple",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 4999.0
},
"sort" : [
4999.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "2",
"_score" : null,
"_source" : {
"title" : "华为手机",
"images" : "http://www.gulixueyuan.com/hw.jpg",
"price" : 4999.0
},
"sort" : [
4999.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : null,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
},
"sort" : [
3999.0
]
}
]
}
}
2. 多字段排序
假定我们想要结合使用 price和 _score(得分) 进行查询,并且匹配的结果首先按照价格排序,然后按照相关性得分排序:
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {
"order": "desc"
}
},
{
"_score":{
"order": "desc"
}
}
]
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : null,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"title" : "apple手机",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 5999.0
},
"sort" : [
5999.0,
1.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
},
"sort" : [
5999.0,
1.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"title" : "apple",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 4999.0
},
"sort" : [
4999.0,
1.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "华为手机",
"images" : "http://www.gulixueyuan.com/hw.jpg",
"price" : 4999.0
},
"sort" : [
4999.0,
1.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "小米手机",
"images" : "http://www.gulixueyuan.com/xm.jpg",
"price" : 3999.0
},
"sort" : [
3999.0,
1.0
]
}
]
}
}
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。
在百度搜索"京东"
在京东网站搜索“小米”
高亮显示的html分析
通过开发者工具查看高亮数据的html代码实现:
高亮查询请求
ElasticSearch可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。
在使用match查询的同时,加上一个highlight属性:
pre_tags:前置标签
post_tags:后置标签
fields:需要高亮的字段
title:这里声明title字段需要高亮,后面可以为这个字段设置特有配置,也可以空
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"match": {
"title": "华为"
}
},
"highlight": {
"pre_tags": "",
"post_tags": "",
"fields": {
"title": {}
}
}
}
响应结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.6931472,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "2",
"_score" : 0.6931472,
"_source" : {
"title" : "华为手机",
"images" : "http://www.gulixueyuan.com/hw.jpg",
"price" : 4999.0
},
"highlight" : {
"title" : [
"华为手机"
]
}
}
]
}
}
from:当前页的起始索引,默认从0开始。 from = (pageNum - 1) * size
size:每页显示多少条
发送请求:
# 请求方法:GET
GET /shopping/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {
"order": "desc"
}
},
{
"_score":{
"order": "desc"
}
}
],
"from": 0,
"size": 2
}
响应结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : null,
"hits" : [
{
"_index" : "shopping",
"_type" : "product",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"title" : "apple手机",
"images" : "http://www.gulixueyuan.com/apple.jpg",
"price" : 5999.0
},
"sort" : [
5999.0,
1.0
]
},
{
"_index" : "shopping",
"_type" : "product",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"title" : "小米电视",
"images" : "http://www.gulixueyuan.com/xmds.jpg",
"price" : 5999.0
},
"sort" : [
5999.0,
1.0
]
}
]
}
}