es DSL语法

kibana版

GET _search
{
  "query": {
    "match_all": {}
  }
}
#测试分词器
POST /_analyze
{
  "text":"程序员",
  "analyzer":"ik_max_word"
}

#创建索引库
PUT page
{
  "mappings": {
    "properties": {
      "info":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "email":{
        "type": "keyword",
        "index": false
      },
      "name":{
        "type": "object",
        "properties": {
          "firstName":{
            "type":"keyword",
            "index":false
          }
        }
      }
    }
  }
}

# 添加一个字段
PUT page/_mapping
{
  "properties":{
    "age":{
      "type":"integer",
      "index":false
    }
  }
}
#查询索引
GET /page/_doc/1

#删除索引
DELETE /page

#添加一条
POST /page/_doc/1
{
  "info":"page的个人信息",
  "age":18,
  "email":"O20110003",
  "name":{
    "firstName":"奇",
    "lastName":"佩"
  }
}

#全量修改,先删除后新增,不存在会新增
PUT /page/_doc/11
{
  "info":"page的个人信息",
  "age":18,
  "email":"O20110003",
  "name":{
    "firstName":"奇",
    "lastName":"佩"
  }
}

# 指定修改
POST /page/_update/11
{
  "doc": {
    "info":"假的个人信息"
  }
}

GET /hotel/_doc/46829

GET /hotel/_search
# 搜索全部
GET /hotel/_search
{
  "query": {
    "match_all": {}
  }
}

# 指定字段或all查询 
GET /hotel/_search
{
  "query": {
    "match": {
      "name": "7赛格"
    }
  }
}

# 多个字段查询(任意字段满足即可查询出结果)
GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "7天",
      "fields": ["brand","name"]
    }
  }
}
# 精确匹配
GET /hotel/_search
{
  "query": {
    "term": {
      "city": {
        "value": "深圳"
      }
    }
  }
}


# 范围匹配(价格在200以内的)
GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 10,
        "lte": 200
      }
    }
  }
}

# 附近查找(15公里以内的)
GET /hotel/_search
{
  "query": {
    "geo_distance":{
      "distance": "15km",
      "location": "31.21, 121.5"
    }
  }
}

# 算分函数
GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "all": "外滩"
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "brand": "如家"
            }
          },
          "weight": 10
        }
      ],
      "boost_mode": "sum"
    }
  }
}
# bool 查询  must参与算分   must_not 和 filter不参与算分
GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "如家"
          }
        }
      ],
      "must_not": [
        {
          "range": {
            "price": {
              "gt": 400
            }
          }
        }
      ],
      "filter": [
        {
          "geo_distance": {
            "distance": "10km",
            "location": {
              "lat": 31.21,
              "lon": 121.5
            }
          }
        }
      ]
    }
  }
}

# sort排序
GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price":"asc"
    },
    {
      "score":"desc"
    }
  ]
}


# 查找附近15km内的酒店

GET /hotel/_search
{
  "query": {
   "geo_distance":{
     "distance":"15km",
     "location":"31.0346611,121.612282"
   }
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 31.0346611,
          "lon": 121.612282
        },
        "order": "asc",
        "unit": "km"
      }
    }
  ]
}


# 分页 限制最多1万条

GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 20
}

# 查到sort给search_after使用
GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price":"asc"
    }
  ],
  "size": 2
}

# 拿到上一个查询到的sort 往后查
GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "search_after":[135]
  ,
  "sort": [
    {
      "price":"asc"
    }
  ],
  "size": 2
}


# 高亮显示 默认高亮包裹em标签  require_field_match 不需要字段匹配
GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "require_field_match": "false"
      },
      "brand": {
        "require_field_match": "false" 
      }
    }
  }
}

# 聚合搜索
GET /hotel/_search
{
  "size": 0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "size": 10
      }
    }
  }
}

# 嵌套聚合(总数、最小、最大、平均、和)
GET /hotel/_search
{
  "size": 0,
  "aggs": {
    "brandAgg": {
      "terms": {
        "field": "brand",
        "size": 10,
        "order": {
          "scoreAgg.avg": "desc"
        }
      }
      , "aggs": {
        "scoreAgg": {
          "stats": {
            "field": "score"
          }
        }
      }
    }
  }
}


REST Client

es手册

package com.page;

import com.alibaba.fastjson.JSON;
import com.page.pojo.Hotel;
import com.page.pojo.HotelDoc;
import com.page.service.IHotelService;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.index.similarity.ScriptedSimilarity;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
public class MyTest {
    @Resource
    private IHotelService iHotelService;

    private RestHighLevelClient client;

    @Test
    public void test1() throws IOException {

        CreateIndexRequest request = new CreateIndexRequest("hotel");
        request.source("{\n" +
                "  \"mappings\": {\n" +
                "    \"properties\": {\n" +
                "      \"id\": {\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"name\":{\n" +
                "        \"type\": \"text\",\n" +
                "        \"analyzer\": \"ik_max_word\",\n" +
                "        \"copy_to\": \"all\"\n" +
                "      },\n" +
                "      \"address\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"index\": false\n" +
                "      },\n" +
                "      \"price\":{\n" +
                "        \"type\": \"integer\"\n" +
                "      },\n" +
                "      \"score\":{\n" +
                "        \"type\": \"integer\"\n" +
                "      },\n" +
                "      \"brand\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"copy_to\": \"all\"\n" +
                "      },\n" +
                "      \"city\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"copy_to\": \"all\"\n" +
                "      },\n" +
                "      \"starName\":{\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"business\":{\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"location\":{\n" +
                "        \"type\": \"geo_point\"\n" +
                "      },\n" +
                "      \"pic\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"index\": false\n" +
                "      },\n" +
                "      \"all\":{\n" +
                "        \"type\": \"text\",\n" +
                "        \"analyzer\": \"ik_max_word\"\n" +
                "      }\n" +
                "    }\n" +
                "  }\n" +
                "}", XContentType.JSON);

        client.indices().create(request, RequestOptions.DEFAULT);
    }

    /**
     * 向es添加document
     * @throws IOException
     */
    @Test
    public void add() throws IOException {
        Hotel byId = iHotelService.getById(46829);
        HotelDoc hotelDoc = new HotelDoc(byId);
        IndexRequest request= new IndexRequest("hotel").id(hotelDoc.getId().toString());
        request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
        client.index(request,RequestOptions.DEFAULT );
    }

    /**
     * 查询一条数据
     * @throws IOException
     */
    @Test
    public void get() throws IOException {
        //准备request
        GetRequest hotel = new GetRequest("hotel", "46829");
        //发送请求
        GetResponse response = client.get(hotel, RequestOptions.DEFAULT);
        //从响应中拿到数据
        String json = response.getSourceAsString();
        //装换成实体类
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);

    }

    /**
     * 修改一条数据
     * @throws IOException
     */
    @Test
    public void update() throws IOException {
        //准备修改请求
        UpdateRequest updateRequest = new UpdateRequest("hotel","46829");
        //准备修改的数据
        Map<String, Object> map = new HashMap<>();
        map.put("price",725);
        //填充
        updateRequest.doc(map);
        //发送请求
        UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(update);

    }

    /**
     * 删除一条数据
     * @throws IOException
     */
    @Test
    public void delete() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("hotel","46829");

        client.delete(deleteRequest,RequestOptions.DEFAULT  );

    }


    /**
     * 批量添加数据
     * @throws IOException
     */
    @Test
    public void bulk() throws IOException {
        BulkRequest request = new BulkRequest();
        List<Hotel> list = iHotelService.list();
        for (Hotel hotel : list) {
            HotelDoc hotelDoc = new HotelDoc((hotel));
            request.add(new IndexRequest("hotel")
                            .id(hotelDoc.getId().toString())
                            .source(JSON.toJSONString(hotelDoc),XContentType.JSON));
        }
        client.bulk(request,RequestOptions.DEFAULT);
    }

    /**
     * matchAll查询
     * @throws IOException
     */
    @Test
    public void searchMatchAll() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        request.source().query(QueryBuilders.matchAllQuery());
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handelResponse(response);
    }

    /**
     * match查询
     * @throws IOException
     */
    @Test
    public void searchMatch() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        request.source().query(QueryBuilders.matchQuery("name","如家"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handelResponse(response);
    }

    /**
     * bool查询
     * @throws IOException
     */
    @Test
    public void bool() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.matchQuery("name","如家"));//name是如家
        boolQuery.mustNot(QueryBuilders.rangeQuery("price").gt(400));//小于400
        boolQuery.filter(QueryBuilders.geoDistanceQuery("location").distance("10km").point(31.21,121.5));
        request.source().query(boolQuery);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handelResponse(response);
    }

    /**
     * 组合查询
     */
    @Test
    public void sort() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        //查询
        request.source().query(QueryBuilders.matchQuery("name","如家"));
        //排序
        request.source().sort("price", SortOrder.ASC).sort("score",SortOrder.DESC);
        //分页  第一页,每页两条数据
        request.source().from(1).size(2);

        //高亮字段封装
        ArrayList<HighlightBuilder.Field> fiedsList = new ArrayList<>();
        fiedsList.add(new HighlightBuilder.Field("name").requireFieldMatch(false));
        fiedsList.add(new HighlightBuilder.Field("brand").requireFieldMatch(false));
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.fields().addAll(fiedsList);
        //高亮
        request.source().highlighter(highlightBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handelResponse(response);
    }

    @Test
    public void testSearch() throws IOException {
        String keyword = "如家";//关键字
        int page = 1;//页数
        int size = 4;//页大小
        String city = "上海";//城市
        String brand = "如家";//品牌
        String starName = "二钻";//星级
        int minPrice = 300;//最小价格
        int maxPrice = 600;//最大价格
        String location = "31.21,121.5";
        SearchRequest request = new SearchRequest("hotel");

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //关键字搜索
        if(keyword==null||keyword.equals("")){
            boolQuery.must(QueryBuilders.matchAllQuery());
        }else{
            boolQuery.must(QueryBuilders.matchQuery("name",keyword));
        }
        //城市搜索
        if(city!=null && !city.equals("")){
            boolQuery.filter(QueryBuilders.termQuery("city",city));
        }
        //品牌搜索
        if(brand!=null && !brand.equals("")){
            boolQuery.filter(QueryBuilders.termQuery("brand",brand));
        }
        //星级搜索
        if(starName!=null && !starName.equals("")){
            boolQuery.filter(QueryBuilders.termQuery("starName",starName));
        }
        //价格区间
        boolQuery.filter(QueryBuilders.rangeQuery("price").gte(minPrice).lte(maxPrice));
        //算分控制
        FunctionScoreQueryBuilder functionScoreQueryBuilder =
                QueryBuilders.functionScoreQuery(
                        //原始算分
                        boolQuery,
                        //其中一个function score
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                                new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                        //过滤条件
                                        QueryBuilders.termQuery("isAD",true),
                                        //权重
                                        ScoreFunctionBuilders.weightFactorFunction(10)
                                )
                        }
                        );//.boostMode(CombineFunction.SUM);//相加

        request.source().query(functionScoreQueryBuilder);


        //分页
        request.source().from((page-1)*size).size(size);
        //request.source().sort("_score");  //默认分值排序自定义排序_score为空
        //附近地理坐标排序
        if(location!=null && !location.equals("")){
            request.source().sort(
                    SortBuilders.geoDistanceSort("location",new GeoPoint(location))
                    .order(SortOrder.ASC)
                    .unit(DistanceUnit.KILOMETERS));
        }



        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handelResponse(response);
    }

    /**
     * 测试聚合搜索
     */
    @Test
    public void testAgg() throws IOException {
        SearchRequest request = new SearchRequest("hotel");

        request.source().aggregation(
                AggregationBuilders
                        .terms("brandAgg")
                        .field("brand")
                        .size(10));
        request.source().size(0);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        Aggregations aggregations = response.getAggregations();
        Terms term = aggregations.get("brandAgg");
        List<? extends Terms.Bucket> buckets = term.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println(bucket.getKeyAsString());
        }
    }

    private void handelResponse(SearchResponse response) {
        //解析返回数据
        SearchHits hits = response.getHits();
        //查询总数
        long total = hits.getTotalHits().value;
        System.out.println("查询到总数:"+total);
        //遍历每一个结果
        for (SearchHit hit : hits.getHits()) {
            HotelDoc hotelDoc = JSON.parseObject(hit.getSourceAsString(), HotelDoc.class);
            System.out.println("当前分数:"+hit);
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if(!CollectionUtils.isEmpty(highlightFields)){
                HighlightField highlightName = highlightFields.get("name");
                //取出高亮的第一个
                if(highlightName !=null){
                    String name = highlightName.getFragments()[0].toString();
                    hotelDoc.setName(name);
                }

                HighlightField highlightbran = highlightFields.get("brand");
                //取出高亮的第一个
                if(highlightbran !=null){
                    String brand = highlightbran.getFragments()[0].toString();
                    hotelDoc.setBrand(brand);
                }
            }
            if(hit.getSortValues().length>0){
                Object sortValue = hit.getSortValues()[0];

                System.out.println("距离"+String.format("%.2f",sortValue)+"km");
            }


            System.out.println(hotelDoc);
        }
    }


    @BeforeEach
    public void setClient(){
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.96.128:9200")
        ));
    }

    @AfterEach
    public void close() throws IOException {
        this.client.close();
    }

}



上一篇:java中SpringBoot项目定时将MySql数据同步到ES中


下一篇:Zookeeper 3.5.7(铲屎官)学习教程