es入门
程序员文章站
2022-07-05 14:00:33
...
1 ES的基本操作
(1) 完成es的crud
index : 索引库 (es) 数据库(database) 索引库 index库(lucene)
type : 表(类型) table documents
id:某一个条数据 column document(field)
(2)es的crud
#新增
PUT crm/employee/1
{
"name":"xxxx",
"age":18
}
#查询
GET crm/employee/1
#修改
POST crm/employee/1
{
"name":"yyyy",
"age":28
}
#删除
DELETE crm/employee/1
#没有指定id 字段生成id
POST crm/employee
{
"name":"yyyy",
"age":28
}
# AW8iLW-mRN4d1HhhqMMJ
GET crm/employee/AW8iLW-mRN4d1HhhqMMJ
GET _search
(3)es 查询特殊的写法
# 查询所有
GET _search
#漂亮格式
GET crm/employee/AW8iLW-mRN4d1HhhqMMJ?pretty
#指定返回的列
GET crm/employee/AW8iLW-mRN4d1HhhqMMJ?_source=name,age
#不要元数据 只返回具体数据
GET crm/employee/AW8iLW-mRN4d1HhhqMMJ/_source
(4)局部修改
#修改 --覆盖以前json
POST crm/employee/AW8iLW-mRN4d1HhhqMMJ
{
"name":"yyyy888"
}
#局部更新
POST crm/employee/AW8iLW-mRN4d1HhhqMMJ/_update
{
"doc":{
"name":"baocheng"
}
}
(5)批量操作—了解
POST _bulk
{ "delete": { "_index": "itsource", "_type": "employee", "_id": "123" }}
{ "create": { "_index": "itsource", "_type": "blog", "_id": "123" }}
{ "title": "我发布的博客" }
{ "index": { "_index": "itsource", "_type": "blog" }}
{ "title": "我的第二博客" }
(6)批量查询
普通查询:
GET crm/employee/id
批量查询:
GET itsource/blog/_mget
{
"ids" : [ "123", "AW8iQAxERN4d1HhhqMML" ]
}
(7)查询条件
#分页查询
GET crm/student/_search?size=3
GET crm/student/_search?from=2&size=2
#根据条件查询 --如果条件比较多 就不适合
GET crm/student/_search?q=age:200 表示查询age=200的人
GET crm/student/_search?size=3&q=age[200 TO 800] 查询age范围到200到800的人,并查询三条数据
如果上面的查询涉及条件比较多,就不适合使用
2 DSL查询与过滤
SQL是关系型数据库查询语言
2.1 什么叫DSL
由ES提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。
DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。
DSL分成两部分:
DSL查询
DSL过滤
2.2 DSL过滤和DSL查询在性能上的区别:
(1) 过滤结果可以缓存并应用到后续请求。
(2) 查询语句同时匹配文档,计算相关性,所以更耗时,且不缓存。
(3)过滤语句可有效地配合查询语句完成文档过滤。
原则上,使用DSL查询做全文本搜索或其他需要进行相关性评分的场景,其它全用DSL过滤。
2.3 DSL查询
GET crm/student/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 3,
"_source": ["name", "age"],
"sort": [{"age": "asc"}]
}
2.4 DSL过滤
#DSL过滤 --> name = 'tangtang' --支持缓存
#select * from student where name=tangtang and age = 500
GET crm/student/_search
{
"query": {
"bool": {
"must": [
{"match": {
"name": "tangtang"
}}
],
"filter": {
"term":{"age":500}
}
}
},
"from": 0,
"size": 3,
"_source": ["name", "age"],
"sort": [{"age": "asc"}]
}
#select * from student where age = 500 and name != 'tangtang'
GET crm/student/_search
{
"query": {
"bool": {
"must_not": [
{"match": {
"name": "tangtang"
}}
],
"filter": {
"term":{"age":500}
}
}
},
"from": 0,
"size": 3,
"_source": ["name", "age"],
"sort": [{"age": "asc"}]
}
2.5 其它和自定义操作
POST _analyze
{
"analyzer":"ik_smart",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
# 就给字段指定分词词 --->文档映射处理
GET crm/student/_search
GET crm/_mapping/student
# 给每个字段指定类型(包括分词器) --给数据库的字段指定类型
# 指定类型时期,在创建的时候,开始指定
# 删除库
DELETE
# 创建库
PUT shop
# 指定类型
POST shop/goods/_mapping
{
"goods": {
"properties": {
"price": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
}
}
}
}
# 存值
PUT shop/goods/1
{
"price":8888,
"name":"最新产品给你用一下"
}
# 查看字段映射类型 --指定分词器
GET shop/_mapping/goods
# ---------- 自己规则--------------------------------
DELETE shop
PUT shop
PUT _template/global_template
{
"template":"*",
"settings": { "number_of_shards": 1 },
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"dynamic_templates": [
{
"string_as_text": {
"match_mapping_type": "string",
"match": "*_text",
"mapping": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
},
{
"string_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}}
PUT shop/goods/1
{
"name":"zhangsanfeng",
"age":18,
"info_text":"zhangsnafeng是一代宗师"
}
# 查看字段是否指定类型
GET shop/_mapping/goods
java基本操作
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.2.2</version>
</dependency>
package cn.itsource.es;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestEs {
//连接es服务方法 嗅探方式 --springcloud yml
public TransportClient getClient() throws Exception{
Settings settings = Settings.builder()
.put("client.transport.sniff", true).build();
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
return client;
}
//新增
@Test
public void testES() throws Exception{
//得到client
TransportClient client = getClient();
IndexRequestBuilder builder = client.prepareIndex("aisell", "user", "1");
Map mp = new HashMap();
mp.put("name","xxxyy");
mp.put("age",18);
builder.setSource(mp);
IndexResponse indexResponse = builder.get();
System.out.println(indexResponse);
client.close();
}
//查询 --springdata es
@Test
public void testGet() throws Exception{
//得到client
TransportClient client = getClient();
System.out.println(client.prepareGet("aisell", "user", "1").get().getSource());
client.close();
}
//修改
@Test
public void testUpdate() throws Exception{
TransportClient client = getClient();
IndexRequest indexRequest = new IndexRequest("aisell", "user", "1");
Map mp = new HashMap();
mp.put("name","test123");
mp.put("age",28);
//不存在 就新增 存在 就更新
UpdateRequest updateRequest = new UpdateRequest("aisell", "user", "1").doc(mp).upsert(indexRequest);
//执行
client.update(updateRequest).get();
client.close();
}
//删除
@Test
public void testDel() throws Exception{
TransportClient client = getClient();
client.prepareDelete("aisell","user","1").get();
client.close();
}
//批量操作
@Test
public void testBulk() throws Exception{
TransportClient client = getClient();
BulkRequestBuilder req = client.prepareBulk();
for(int i=1;i<50;i++){
Map mp = new HashMap();
mp.put("name","tt"+i);
mp.put("age",18+i);
req.add(client.prepareIndex("shoppings","goods",""+i).setSource(mp));
}
BulkResponse responses = req.get();
if(responses.hasFailures()){
System.out.println("插错了");
}
}
//DSL查询 -- 分页 排序 过滤
/**
*
*/
@Test
public void testDSL() throws Exception{
//得到client对象
TransportClient client = getClient();
//得到builder
SearchRequestBuilder builder = client.prepareSearch("shoppings").setTypes("goods");
//得到bool对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//得到must
List<QueryBuilder> must = boolQuery.must();
must.add(QueryBuilders.matchAllQuery());
//添加filter过滤器
boolQuery.filter(QueryBuilders.rangeQuery("age").gte("18").lte("58"));
builder.setQuery(boolQuery);
//添加分页
builder.setFrom(0);
builder.setSize(10);
//设置排序
builder.addSort("age", SortOrder.DESC);
//设置查询字段
builder.setFetchSource(new String[]{"name","age"},null);
//取值
SearchResponse response = builder.get();
//得到查询内容
SearchHits hits = response.getHits();
//得到命中数据 返回数组
SearchHit[] hitsHits = hits.getHits();
//循环数组 打印获取值
for (SearchHit hitsHit : hitsHits) {
System.out.println("得到结果"+hitsHit.getSource());
}
}
}
Springboot集成es
导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
yml配置
server:
port: 2050
spring:
application:
name: es-server
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 127.0.0.1:9300
映射类
/**
* ES文件对象 ,作用 :
* 1.用来创建索引库 ,
* 2.用户做文档映射
* 3.ES存储数据时也要用这个对象封装
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "hrmtest",type = "employeetest")
public class EmployeeDoc {
@Id
private Long id;
@Field(type = FieldType.Keyword) //指定为 不分词
private String name;
@Field(type =FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")
private String intro;
@Field(type = FieldType.Integer)
private Integer age;
}
repository层
@Repository
public interface CourseElasticsearchRepository extends ElasticsearchRepository<CourseDoc,Long> {
}
service
public interface ICourseEsService {
PageList queryCourses(CourseQuery courseQuery);
}
service.impl
@Service
public class CourseEsServiceImpl implements ICourseEsService {
@Autowired
private CourseElasticsearchRepository courseElasticsearchRepository;
/**
sortField: ""
sortType: "desc"
page: 1
rows: 12
* @param courseQuery
* @return
*/
@Override
public PageList<CourseDoc> queryCourses(CourseQuery courseQuery) {
//本地查询
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
//添加条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//DSL查询
List<QueryBuilder> must = boolQueryBuilder.must();
//关键字
if(StringUtils.isNotBlank(courseQuery.getKeyword())){
must.add(QueryBuilders.matchQuery("name",courseQuery.getKeyword()));
}
//DSL过滤
List<QueryBuilder> filter = boolQueryBuilder.filter();
//类型
if(courseQuery.getProductType() != null){
filter.add(QueryBuilders.termQuery("courseTypeId",courseQuery.getProductType()));
}
//最小价格 ,priceMin: null
if(courseQuery.getPriceMin() != null){
filter.add(QueryBuilders.rangeQuery("price").gte(courseQuery.getPriceMin()));
}
//最大价格,priceMax: null
if(courseQuery.getPriceMax() != null){
filter.add(QueryBuilders.rangeQuery("price").lte(courseQuery.getPriceMax()));
}
nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
//排序
if(StringUtils.isNotBlank(courseQuery.getSortField())){
//排序的列
String sortOrderFiled = null;
//xl ; pl
String sortFieldSn = courseQuery.getSortField();
switch (sortFieldSn.toLowerCase()){
case "xl" : sortOrderFiled = "payCount";break;
case "pl" : sortOrderFiled = "commentCount";break;
case "xp" : sortOrderFiled = "onlineTime";break;
case "jg" : sortOrderFiled = "price";break;
case "rq" : sortOrderFiled = "viewCount";break;
}
//排序方式
SortOrder sortType = SortOrder.DESC;
switch (courseQuery.getSortType().toLowerCase()){
case "asc": sortType = SortOrder.ASC;
}
nativeSearchQueryBuilder.withSort(new FieldSortBuilder(sortOrderFiled).order(sortType));
}
//分页
nativeSearchQueryBuilder.withPageable(PageRequest.of(courseQuery.getPage()-1 , courseQuery.getRows()));
//查询
Page<CourseDoc> page = courseElasticsearchRepository.search(nativeSearchQueryBuilder.build());
//结果封装
List<CourseDoc> list = page.getContent();
long total = page.getTotalElements();
return new PageList<>(total , list);
}
}
controller
/**
* @date 2020/1/6.
* 全文检索服务
*/
@RestController
@RequestMapping("/es")
public class ElasticSearchController {
@Autowired
private CourseElasticsearchRepository courseElasticsearchRepository;
@Autowired
private ICourseEsService courseEsService;
//查询课程
@RequestMapping("/queryCourses")
public PageList queryCourses(@RequestBody CourseQuery courseQuery){
return courseEsService.queryCourses(courseQuery);
}
//存储
@RequestMapping("/saveCourse")
public AjaxResult saveCousrc(@RequestBody CourseDoc courseDoc){
courseElasticsearchRepository.save(courseDoc);
return AjaxResult.me();
}
//删除
@RequestMapping("/deleteById/{id}")
public AjaxResult deleteById(@PathVariable("id") Long id){
courseElasticsearchRepository.deleteById(id);
return AjaxResult.me();
}
}