elasticsearch的基本概念
1. 倒排索引
(1) 文档(document): 每条数据就是一个文档
(2) 词条(term): 文档按照语义分成的词语
(3) 倒排索引的案例: 词条是不会重复的,因此在建立索引的时候如图
2. mapping
(1) 理解: mapping简单理解为索引库字段的约束。
(2) 常见的mapping属性:
type: 字段数据类型,常见类型:
字符串: text(可分词的文本),keyword(精确值,例如:皮牌,国家,ip等)
数值: long,integer,short,byte,double,float
布尔: boolean
日期: date
对象: object
index: 是否创建索引,默认true(就可以参与搜索,如果是false,就不会创建索引,也就不会参与搜索)
analyzer: 使用哪种分词器
properties: 该字段的子字段
3. 索引库操作
# 创建聚合支付索引库
# email不参与搜索,index=false
PUT /collect_pay
{
"mappings": {
"properties": {
"info": {
"type": "text",
"analyzer": "ik_smart"
},
"email": {
"type": "keyword",
"index": false
},
"name": {
"type": "object",
"properties": {
"firstName": {
"type": "keyword"
},
"lastName": {
"type": "keyword"
}
}
}
}
}
}
# 查看索引库
get /collect_pay
注意:定义好了mapping后,禁止修改已有的mapping字段,但是可以新增新的字段mapping
# 修改索引库,添加新字段
put /collect_pay/_mapping
{
"properties":{
"age":{
"type":"integer"
}
}
}
4. document的crud
(1) 如果新增的时候没有添加id,则es会自动生成一个_id
// 新增文档
post /collect_pay/_doc/1
{
"info":"程序员Java讲师",
"email":"sdf@126.com",
"name":{
"firstName":"珊珊",
"lastName":"丁"
}
}
// 查询文档
get /collect_pay/_doc/1
// 删除文档
DELETE /collect_pay/_doc/1
注意:match查询非字符串的字段的时候,是精确查询,例如:
GET bank/_search
{
"query":{
"match":{
"balance":16789
}
}
}
使用match进行全文检索,匹配的字符串会进行分词,默认会按照评分进行排序
GET bank/_search
{
"query":{
"match":{
"address":"百润路" //_source的address字段内容中,但是包含"百润路"的字段都会被检索出来
}
}
}
GET bank/_search
{
"query":{
"match":{
"address":"浦口 百润路" //_source的address字段内容中,但是包含"百润路" or "浦口" 的字段都会被检索出来
}
match_phrase短语匹配,将需要匹配的值当作一个整体单词(不分词)进行检索,例如:
// 查出address中包含"浦口区百润路"的所有记录,并给出相关性得分
GET bank/_search
{
"query":{
"match_phrase":{
"address":"浦口区百润路"
}
}
}
multi match多字段匹配:也会对检索内容进行分词
GET bank/_search
{
"query":{
"multi_match":{
"query":"mill",
"fields":["state","address"] //state或者address字段中包含mill的都会被检索出来
}
}
}
GET bank/_search
{
"query":{
"multi_match":{
"query":"mill,road",
"fields":["state","address"] //state或者address字段中包含mill或者road的都会被检索出来
}
}
}
5. bool复杂查询
- 需求实现类似于数据库:where age = 40 and state != ‘1’;
GET bank/_search
{
"query":{
"bool":{
"must":[
{"match":{"age":"40"}} //可以是多个条件
],
"must_not":[
{"match":{"state":"1"}}
]
}
}
}
GET bank/_search
{
"query":{
"bool":{
"must":[
{"match":{"age":"40"}} //可以是多个条件
],
"must_not":[
{"match":{"state":"1"}}
],
"should":[
{"match":{"lastname":"walk"}} //应该满足的条件,不满足也行,满足的话评分会高点
]
}
}
}
must,should都会贡献相关性得分
must_not相当于是一个过滤,filter,是不会贡献相关性得分的
GET bank/_search
{
"query":{
"bool":{
"must":[
{
"range":{
"age":{
"gte":18,
"lte":30
}
}
}, //where (age between 18 and 30) and address like '%百润路%'
{
"match":{
"address":"百润路"
}
}
]
}
}
}
##### 替换 #######
GET bank/_search
{
"query":{
"bool":{
"filter":[
{
"range":{
"age":{
"gte":18,
"lte":30
}
}
} // filter检索结果:不会计算相关性得分,可以实现以上的查询效果
]
}
}
}
- 全文检索的字段,不要使用term,使用match作全文检索,默认会分词
- 精确值的查询使用term
GET bank/_search
{
"query":{
"term":{
"age":33
}
}
}
xxx.keyword与match_phrase的区别: xxx.keyword的源数据中,该字段的全部内容就是查询的内容,而match_phrase,只需要源数据字段种包含检索的内容即可
规范: 查询非text字段,使用term, 文本字段使用match
每一个文本字段都可以 .keyword,不分词当作整体去检索
GET bank/_search
{
"query":{
"match":{
"address.keyword":"789 Mad road"
}
}
}
GET bank/_search
{
"query":{
"match_phrase":{
"adress":"789 Mad road" ###### _source的address字段种只要包含"789 Mad road"就会被检索出来
}
}
}