欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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();
    }
}