ElasticSearch的索引机制 和 query dsl语法的使用

ElasticSearch的数据类型

text 被用来索引长文本,建立索引钱会将这些文本进行分词
keyword 不需要分词,可以被用来检索过滤、排序、聚合
数学类型:long integer short byte doucle float
日期类型: date
布尔类型:boolean
二进制:binary
数组类型
对象类型 object
等等基本数据类型,还有许多特定类型如地理位置、Ipv4等等 不过多介绍

倒排索引

ElasticSearch使用一种称为倒排索引的结构,它适用于快速的全文检索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每一个词,都有一个包含它的文档列表

示例:

id内容
1小明
2小丽
3小黑

用分词器将内容自动切分成单词序列,每个文档就转换为由单词序列构成的数据流,需要对每个不通给的单词赋予唯一的单词编号,同事记录下哪些文档包含这个单词,由此我们可以得到每个单词的倒排列表,如下

id单词倒排列表
11,2,3
21
32
43

倒排列表中可以记录单词出现的频率,即该单词在某个文档中出现次数,如下表格

id单词倒排列表
1(1;1),(2;1),(3;1)
2(1;1)
3(2;1)
4(3;1)

倒排列表中还可以记录单词在某个文档中出现的文职信息,如
(1,<1>,1) 表示单词在id为1的文档中出现过一次,位置为1

倒排索引建立规则

Hello 和hello,用户会认为他们是相同的词
dog和dogs 他们有相同的词根
jumped和leap 没有相同的词根,但是他们的意思相近,是同义词
以上情况,应该都能被同一种搜索条件搜索到
所以,在建立倒排所以的时候,es会使用标准化规则,以确保上面的例子都能被搜索到。

分词器

从一串文本中且分出一个一个的词条,并对没个词条进行标准化。包括三部分:
1.charactre fiter,分词之前的预处理,过滤掉HTML标签,特殊符号转换等
2.tokenizer,分词
3.token filter,标准化(单复数、大小写、同义词等)

内置分词器

1.standard分词器(默认分词器),他会将词汇转换成小写形式,并去除停用词和标点符号,支持中文,采用的方法为单字切分
2.simpl分词器,首先会通过非字母字符来分割文本信息,将词汇单元统一为小写形式,该分词器会去掉数学类型的字符
3.whitespace分词器,仅去掉空格,对字符没有lowcase化,不支持中文,不对生成的词汇单元进行其他标准化处理
4.language分词器,特定语言分词器,不支持中文

kibana使用

创建索引
PUT  /lib/ 
{
	"settings":{
		"index":{
			"number_of_shards": 3,
			"number_of_replicas": 0
		}
	}
}

/lib/ --索引的名称 ,number_of_shards – 分片的数量,number_of_replicas – 备份的数量
//如果不设置settings 则使用默认配置 number_of_shards为5 ,number_of_replicas为1

PUT /lib/user/1
{
“first_name”:“xiaowang”,
“last_name”:“laowang”,
“age”:55,
“about”:“I like to collect rockalbums”,
“interrests”:[“music”]
}
//在索引lib下添加类型为user,id为1的一条数据
如果不指定id,则使用POST,id由es服务器自动生成

查看索引

查看索引配置
GET /lib/_settgins
查看所有索引的配置
GET /_all/_settgins
查看指定id的数据
GET /lib/user/1
//指定显示结果集字段
GET /lib/user/1?_source=age,about

更新索引

多次put会覆盖掉前一次
如果要更新指定字段,则需要post
POST /lib/user/1/_update
{
“doc”:{
“age”:56
}
}

删除

DELETE /lib/user/1 --删除指定数据

DELETE /lib2/ --删除索引

批量获取
GET /_mget
{
  "docs":[
      {
        "_index":"lib",
        "_type":"user",
        "_id":1
      },
       {
        "_index":"lib",
        "_type":"user",
        "_id":2
      } 
   ]
}

//分别指定不同的字段

GET /_mget
{
  "docs":[
      {
        "_index":"lib",
        "_type":"user",
        "_id":1,
        "_source":["age","intersts"]
      },
       {
        "_index":"lib",
        "_type":"user",
        "_id":2,
        "_source":"intersts"
      } 
   ]
}

//简化写法,也可以单独指定

GET /lib/user/_mget
{
  "docs":[
      {
        "_id":1
      },
       {
       	"type":"user2",
        "_id":2
      } 
   ]
}

//如果是同类型的批量获取 还可以再次简化
GET /lib/user/_mget
{
“ids”:[“1”,“2”]
}
//搜索 排序
GET /lib/user/_search?q=last_name:laoli&sort=age:desc

query查询

term查询

//复杂 条件查询

GET /lib/user/_search
{
	"query":{
			"terms":{
					"interests":["music"]
				}
	 }
}

//分页

GET /lib/user/_search
{
  "from":0,
  "size":2,
	"query":{
			"terms":{
					"interests":["music"]
				}
	 }
}

//如果需要显示版本号在上边的json中加入"version":true

match查询

GET /lib/user/_search
{

"query":{
		"match":{
				"name":"zhaoliu  tianqi"
			}
 }

}
会查询出包含zhaoliu、tianqi的所有数据。term和match的主要区别在于,term不使用分词器,对值进行完全匹配,match会对查找条件进行分词,匹配倒排索引。
精确查找使用使用term,匹配查找使用match

//查询全部

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

//多filed查询
GET /lib/user/_search

{
	"query":{
			"multi_match":{
			  "query":"laowang,xiaoli",
			  "fields":["last_name,"first_name"]
			}
	 }
}

//短语匹配,匹配指定字段 相当于模糊查询
GET /lib/user/_search
{

"query":{
		"match_phrase":{
		  "last_name":"laowang shi shei"
		}
 }

}
//指定结果集
GET /lib/user/_search
{

"query":{
		"match_all":{}
 },
 "_source":["last_name","age"]

}
或者

GET /lib/user/_search
{

	"query":{
			"match_all":{}
	 },
	 "_source":{
	   "includes":"*name",
	   "excludes": ["age"]
	 }
}

//排序
GET /lib/user/_search
{
“query”:{
“match_all”:{}
},
“sort”:{
“age”:{
“order”:“asc”
}
}
}
//查询指定日期


GET /lib/user/_search
{
	"query":{
			"range":{
			  "birthday":{
			    "from":"1991-12-120",
			    "to":"2020-02-20",
			    "include_lower":true,
			    "include_upper":false
			  }
			}
	 }
}
wildcard查询

//可以使用通配符*和?

GET /lib/user/_search
{
	"query":{
			"wildcard":{"last_name":"lao*"}
	 }
}
fuzzy 实现模糊查询

GET /lib/user/_search
{
“query”:{
“fuzzy”:{
“last_name”:“liaolii”
}
}
}
同样可以查询出last_name 值为laoli的数据

过滤查询

属性介绍:
must 必须满足
should 满足其中一个即可
must_not 不必满足

只查询满足的条件

  GET /lib5/user/_search
 {
   "query": {
     "bool": {
       "filter": {
         {
           "terms":{
            "name":"laowang"
           }
         }
       }
     }
   }
 }
bool过滤查询

满足年龄是25或者生日是2020-02-20,不必满足年龄是30

 GET /lib5/user/_search
 {
   "query": {
     "bool": {
       "should": [
          {"term":{"age":25}},
          {"term":{"birthdate":"2020-02-20"}}
        ],
        "must_not": {
          "term":{"age":30}
        }
     }
   }
 }
高亮搜索结果
GET /lib/user/_search
{
	"query":{
			"match":{
			  "last_name":"laoli"
			}
	 },
	 "highlight":{
	   "fields":{
	     "last_name":{}
	   }
	 }
}

//会将要高亮显示的字段值用标签包裹

Bulk API 实现批量操作

批量添加
POST /lib2/emp/_bulk
{"index":{"_id":1}}
{"name":"xiaowang","age":1}
{"index":{"_id":2}}
{"name":"xiaoli","age":2}

//所有操作一起执行
POST /lib2/emp/_bulk
{“delete”:{"_index":“lib2”,"_type":“emp”,"_id":“2”}} --删除
{“create”:{"_index":“lib3”,"_type":“emp”,"_id":“100”}} --创建新的索引和类型并添加
{“name”:“wangwu”}
{“index”:{"_index":“lib3”,"_type":“emp”}} --添加,id由es服务器生成
{“name”:“zhaoliu”}
{“update”:{"_index":“lib2”,"_type":“emp”,"_id":“1”}} – 更新
{“doc”:{“age”:“50”}}
bulk会把要处理的数据载入到内存中,所以数量是有限制的,最佳的数量取决于硬件、文档的大小和复杂性,一般建议1000-5000个文档,大小建议5-15MB,默认不超过100M,可以再es的配置文件中进行配置

版本控制

es采用了乐观锁来保证数据的一致性,当用户对document进行操作时,需要制定操作的版本,版本号存在冲突时,es会提示冲突并跑异常(VersionConflictEngineException异常)。
内部版本控制使用的是 _version,取值范围 1 -2的63次方-1
外部版本控制:version和version_type=external 配合使用切versioin需要大于es中的version的值
PUT /lib/user/2/?version=4&version_type=external
{
“first_name”:“xiaoli”,
“last_name”:“laoli”,
“age”:55,
“about”:“I like to collect rockalbums”,
“interrests”:[“music”]
}

mapping

GET /lib/usr/_mapping 查看指定类型的mapping映射,默认由es服务器生成,es服务器会根据数据自动判断类型,简称动态映射。
GET /lib/user/_search?q=last_name:laoli

默认情况下,数值、日期不进行分词,只有text类型可以分词。
mapping的属性介绍:
index 是否分词
analyzer 指定分词器,默认standard analyzer
search_analyzer 指定搜索时的分词器,同analyzer 相同
ignore_above 文本超过指定值,将会忽略

//自定义mappingd
es默认会为每一个字段都建立倒排索引,如果不需要需要再mappings中添加index=false,这样该字段不会建立倒排索引,也不会被检索。

PUT /lib4
{
  "settings":{
		"index":{
			"number_of_shards": 3,
			"number_of_replicas": 0
		}
	},
	"mappings":{
		  "users":{
		    "properties":{
		      "name":{"type":"text"},
		      "username":{"type":"text","analyzer":"standard"},
		      "carate_time":{"type":"date","index":false},
		      "age":{"type":"integer"}
		    }
		  }
		}
}
copy_to

//如果多个text类型的field都需要被索引,则在创建mapping的时候,可以将多个field拷贝到一个field,在索引的时候检索这一个字段就可以了,能够显著提升检索性能。

PUT /lib6/user
{
	"properties":{
		"name":{
			"type":"text",
			"copy_to":"fullcontents"
		},
		"address":{
			"type":"text",
			"copy_to":"fullcontents"
		}
	}
}

中文分词器的使用

ik带有两个分词器:ik_max_word,会将文本做最细粒度的拆分,尽可能的拆分出词语。ik_smart,会做最粗粒度的拆分,已被拆分的词语不会再次被其他词语占有

 PUT /lib5
 {
   "settings": {
     "number_of_shards": 3,
     "number_of_replicas": 0
   },
   "mappings": {
     "user":{
       "properties": {
         "name":{"type": "text","analyzer": "ik_max_word"},
         "address":{"type": "text","analyzer": "ik_max_word"},
         "age":{"type": "integer"},
         "interests":{"type": "text","analyzer": "ik_max_word"},
         "birthdat":{"type": "date"}
       }
     }
   }
 }

scroll大数据量查询

如果查询数据量较大,可以使用scroll查询,分批返回数据,达到滚动加载数据的效果,但是他和分页并不是同一个性质,这里要做好区分。


 GET /lib7/user/_search?scroll=1m   --指定每批查询时间最大为1分钟
 {
   "query": {
     "match_all": {}
   },
   "sort": ["_doc"],  -- 不按默认的相关度排序,提高性能
   "size":3  -- 每批次查询3条
 }
 //每次下旬结果会返回scroll_id,下次查询直接传递该值

 GET /_search/scroll
 {
   "scroll":"1m",
   "scroll_id":"DnF1ZXJ5VGhlbkZldGNoAwAAAAAAAAABFmFwWWdERWwxUXJPWEN0SzIzS2duNkEAAAAAAAAAAhZhcFlnREVsMVFyT1hDdEsyM0tnbjZBAAAAAAAAAAMWYXBZZ0RFbDFRck9YQ3RLMjNLZ242QQ=="
 }

聚合查询

统计keyword字段的keyword类型的出现频率(由于keyword指定了text和keword两种类型),


 
GET /test_index/_search
{
    "size": 0,
    "aggs":{
        "word_count":{
            "terms":{
                "field":"keyword.keyword",
                "size": 2
            }
        }
    }
}

过滤后聚合

GET /test-index/_search
{
  "size": 0, 
  "query": {
    "term": {
      "type": {
        "value": 3
      }
    }
  },
  "aggs": {
    "word_count": {
      "terms": {
        "field": "keyword"
      }
    }
 }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值