1.ES简介
Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎
2.ES数据结构
数据以json文档的形式存储,多个关联性的文档存储的集合叫做索引,类似关系型数据库中的表,文档中有各个属性(字段),每个属性可以设置不同的类型(type)
2.1 数据类型和映射
简单域类型:
字符串: text, keyword
整数 : byte, short, integ`er, long
浮点数: float, double
布尔型: boolean
日期: date
tips:
text: 默认分词,分词后可模糊搜索 keyword: 存储的字符串当做一个整体,只能精确匹配
复杂域类型:
对象: object(对象的同属性数据会扁平化存储)
{
"title": [ eggs, nest ],
"body": [ making, money, work, your ],
"tags": [ cash, shares ],
"comments.name": [ alice, john, smith, white ],
"comments.comment": [ article, great, like, more, please, this ],
"comments.age": [ 28, 31 ],
"comments.stars": [ 4, 5 ],
"comments.date": [ 2014-09-01, 2014-10-22 ]
}
嵌套对象 : nested(保持对象属性与值的关联关系)
{
"comments.name": [ john, smith ],
"comments.comment": [ article, great ],
"comments.age": [ 28 ],
"comments.stars": [ 4 ],
"comments.date": [ 2014-09-01 ]
}
{
"comments.name": [ alice, white ],
"comments.comment": [ like, more, please, this ],
"comments.age": [ 31 ],
"comments.stars": [ 5 ],
"comments.date": [ 2014-10-22 ]
}
{
"title": [ eggs, nest ],
"body": [ making, money, work, your ],
"tags": [ cash, shares ]
}
规定一个文档包含的属性和其对应的结构称之为映射(schema)
自动映射:es根据文档类型自动生成
手动映射:通过api手动创建
tips:
string类型自动映射为text类型和一个256长度的子类型 keyword对象类型自动映射为object而不是nested
3.ES常用操作
3.1 es写入
PUT http://10.254.254.179:9200/hotel
创建索引(实际请求如图三,下面图片均采用es开发工具截图)
PUT es_hotel_v1
创建别名
PUT /es_hotel_v1/_alias/es_hotel
删除索引
DELETE /es_hotel_v1
创建/更新映射
PUT /es_hotel_v1/_mapping
{
"properties": {
"performance": {
"properties": {
"dom": {
"type": "long"
},
"load": {
"type": "long"
},
"redirect": {
"type": "long"
},
"request": {
"type": "long"
},
"time": {
"type": "long"
},
"unload": {
"type": "long"
},
"whiteScreen": {
"type": "long"
}
}
},
"uuid": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
tips: 映射可增量更新,不可修改已有映射属性类型
写入文档
PUT /es_hotel_v1/_doc
{
"performance": {
"redirect": 0,
"whiteScreen": 2457,
"dom": 671,
"load": 3136,
"unload": 0,
"request": 135,
"time": 1625037737111
},
"uuid":"jsjjfoyhaywoj1uqpkm"
}
3.2 es查询及排序
match
GET /es_hotel_v1/_search
{
"query": {
"match": {
"uuid": "111"
}
}
}
tips: text类型且开启分词属性为模糊匹配,其余为精确查询
bool
GET /plan_price_calendar/_search
{
"query": {
"bool": {
"must": [ //必须满足的条件
{
"term": { //精确匹配
"hotelId": {
"value": "100000006"
}
}
},
{
"terms": { //包含,类似in
"hotelId": [
"100000006",
"100000007"
]
}
},
{
"range": { //范围查询
"hotelId": {
"gte": 100000003,
"lte": 100000009
}
}
}
],
"should": [ //可以满足的条件 or
{}
],
"must_not": [ //必须不满足的条件
{}
],
"filter": [ //内部写法类似must,查询不参与评分
{
"missing": { //缺失查询,类似is null
"field": "hotelId"
}
},
{
"exists": { //存在查询,类似is not null
"field": "hotelId"
}
}
]
}
}
}
tips: 如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但,如果存在至少一条 must 语句,则对 should 语句的匹配没有要求。
Sort 排序
GET /es_hotel_v1/_search
{
"query": {
"match": {
"uuid": "111"
}
},
"sort": [
{
"uuid": {
"order": "desc"
}
}
]
}
3.2.1嵌套文档查询
由于嵌套对象 被索引在独立隐藏的文档中,所以无法直接查询,必须使用 nested 查询
GET /productalias/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"productName": "券包"
}
},
{
"nested": { //nested标识
"path": "projectPriceList", //嵌套对象属性名
"query": {
"bool": {
"must": [
{
"term": {
"projectPriceList.projectId": { //嵌套对象属性
"value": "P012"
}
}
}
]
}
}
}
}
]
}
},
"sort": [
{
"projectPriceList.projectId": { //嵌套对象排序字段
"order": "desc",
"nested": { //嵌套对象标识
"path": "projectPriceList", //嵌套对象属性名
"filter": { //添加上述嵌套对象搜索相同的条件,原因是排序发生在查询执行之后,查询返回的是主文档,如果排序里不加以条件限制,排序将基于主文档对应所有的嵌套对象该属性来排序,而不是满足查询条件的嵌套文档的相应属性来排序
"term": {
"projectPriceList.projectId": {
"value": "P008",
"boost": 1
}
}
}
}
}
}
]
}
3.3 小技巧
3.3.1 更新已有映射属性类型
新建一个索引
PUT /es_hotel_v2为新索引创建新映射
PUT /es_hotel_v2/_mapping
{
"properties": {
"performance": {
"properties": {
"dom": {
"type": "long"
},
"load": {
"type": "long"
},
"redirect": {
"type": "long"
},
"request": {
"type": "long"
},
"time": {
"type": "long"
},
"unload": {
"type": "long"
},
"whiteScreen": {
"type": "long"
}
}
},
"uuid": {
"type": "keyword" //这里原类型为text更新为keyword
}
}
}reindex旧索引数据至新索引
POST /_reindex
{
"source": {
"index": "es_hotel_v1"
},
"dest": {
"index": "es_hotel_v2"
}
}更新旧索引别名指向新索引
POST /_aliases
{
"actions": [
{ "remove": { "index": "es_hotel_v1", "alias": "es_hotel" }},
{ "add": { "index": "es_hotel_v2", "alias": "es_hotel" }}
]
}删除旧索引
DELETE /es_hotel_v1
3.3.2 部分删除
POST /es_hotel_v1/_delete_by_query
{
"query": {
"match": {
"uuid": "111"
}
}
}
tips: 如果是全量删除,直接删除索引效率更高,由于es存储设计,整个索引会被归类成一个文件夹




