第七章-分布式搜索引擎-ES:全文查询、分词查询、精确查询、地理坐标查询、组合查询(bool、funtion_score)以及RestApi

这篇具有很好参考价值的文章主要介绍了第七章-分布式搜索引擎-ES:全文查询、分词查询、精确查询、地理坐标查询、组合查询(bool、funtion_score)以及RestApi。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

DSL查询文档

DSL查询分类

全文查询、分词查询、非分词查询、地理坐标查询、组合查询

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

match_all 查询所有,不需要查询条件,固定写法_search

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

第一个hits就是命中的数据 ,total就是条数,第二个hits是source嘞

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

全文检索查询

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

我们不要整多个字段查询,参与的字段越多,查询速度越慢,如果有多个字段,可以把这几个字段copy_to到一个字段去查,如all,第一种效查询效率更高

query查询条件text就是输入的内容,比如”酒店“,fields就是字段名字

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

精确查询

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎
 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

term确保搜索的内容,和文档的内容一模一样 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 范围range:gte是大于等于,let小于等于,

如果把e去掉,就是大于不等于,或小于不等于

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

地理坐标查询

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

第一种查询

top_left:是一个点,左上角的点

bottom_right :也是一个点,右下角的点

两个点形成一个矩形,矩形范围内的就是文档能查出来的数据,比如打车,在我这个圆圈只内的车

适合查一定范围内的信息,比如说按照地图找房子,找酒店等

矩形查询的比较少,一般都是一个圆圈

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 第二种查询

field:中心点,有点类似于我的位置,或者家庭住址的位置等,然后周边扩撒

15km,就是以field的中心点画一个半径,根据半径画一个圆,这个圆圈起来的所有的点,就是符合的文档

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

location :是根据中心点(可以自己定位,我的位置)查询在文档符合条件的location的经纬度

字段location:是根据这个点,找文档里在这个距离内符合条件的数据

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

以上查询都叫简单查询 

组合查询,也叫复合查询

人工对搜索排名实现干预,比如百度搜索,我给钱多,就排第一

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

过滤条件,决定那些文档需要加分 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

算分文档三要素

  • 1、那些文档要加分
  • 2、算分函数是啥
  • 3、加权模式是啥 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

查询可以知道外滩的如家分数最低,才4.0分 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

比如说我想让如家跑到第一名去,查询的时候就加上过滤条件算分函数,和算法,给他加了20分,已经是24分了

注意,这里是查询,实际上并不会修改文档,只是在查询的结果集上给分数加了点数而已

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 组合查询

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

案例:价格不高于,就是低于,可以取反

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

dsl语法,注意,放到mast或should里边都会影响算分的,参与算分的越多,性能越差 

GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "如家"
          }
        }
      ],
      "filter": [
        {
          "geo_distance": {
            "distance": "10km",
            "location": {
              "lat": 31.21,
              "lon": 121.5
            }
          }
        }
      ],
      "must_not": [
        {
          "range": {
            "price": {
              "gt": 400
            }
          }
        }
      ]
    }
  }
}

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

将来我们关键字搜索尽量放到must里,其他的尽量放到must_not、filter里 

搜索结果处理

排序

ES默认是根据算分来排序的,分值越高,排序越靠前,但是有时候我们还得按照别的来排序,比如价值等

一旦自己指定排序字段,ES就会放弃打分,这样查询的效率方免也会有一定的提升

keyword类型是字符串,它的排序是按照字母顺序排序,用的比较少

地理坐标排序,比如说到我距离最近的点,做一个升序排序

注意:查询和排序是同级的关系,不是写在query里了

sort排序,就相当于mysql里的orderBy,如果有多个排序,先按照第一个字段排序,第一个字段相等就按照第二个字段排序,和mysql一样

地理坐标排序 unit就是排序后的结果,是按照km展示,还是m展示

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

ppt写法有点不优雅,直接  field:asc 更优雅 ,先按照评分降序,评分相等就按照价格升序

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 获取鼠标点击经纬度-地图属性-示例中心-JS API 2.0 示例 | 高德地图API

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

这个酒店距离我们1278公里,注意,一旦做了排序,_score就是null,就是不会去做相关性算分了 

分页

ES底层有一个默认的分页参数,默认10条

form,size类似mysql的limit和row,从哪开始,几行,几条

这是单机的情况非集群模式,想要查出后10条数据,是截取的,先查出1000条数据,然后截取后10条数据 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

size不配置的话默认是10 ,这是第一页,第二页from就是10,第三页就是20

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

一旦做集群,ES就会把数据拆分,放到不同的服务里,拆分出的每一份我们叫做分片 ,分片里的数据是不一样的,一旦做了集群,我们不能确定这10条数据是哪个片上的

就是说shard1片1上的前1000,在片2上的不一定就排名还是前1千了

做法应该是把所有片上的前1000名都取出来,然后再排序取出前1千名,然后再截取

上千台服务器,查询前1000条数据,那就是1000*1000,然后排序,数量太大了 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 不能超过1万条,可以是1万条 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 一般我们就用from size就行,可以支持随机翻页,向前向后翻页,

search after查询超过1万条,不支持随机翻页,不能像前翻页

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

高亮

其实就是我们搜索的数据,在页面中给加上一个标签,就是高亮了

就是服务端给搜索的关键字给个标签

前端拿到这个标签给个样式就好了

注意:高亮,一定要对关键字高亮,不能用matchall,一定要带上关键字

fields字段可以有多个,比如说标题、文档内容都要高亮,

ES中,默认标签就是em可以不指定 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 查询并没有高亮,原因是:默认情况下ES的搜索字段,必须与高亮字段一致,否则不会高亮

GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}

但是我们现在就要用all来查询,有个字段,需不需要高亮匹配,默认是需要true改成false就可以了


GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "require_field_match": "false"
      }
    }
  }
}

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

都是同级的,和在一起是一个dsl的json风格语句 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

RestClient查询文档

快速入门

source里边封装了各种api,如查询,分页,高亮等等

QueryBulder是个接口,我们用QueryBuilders工具类,里边封装了各种查询,term、match、等

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

解析 ,其实就是逐层解析json,用代码实现

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

getTotalHits拿到的是对象,点它的value属性,就拿到值嘞 

@Test
    void esTest1() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        request.source().query(QueryBuilders.matchAllQuery());
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits responseHits = response.getHits();
        long total = responseHits.getTotalHits().value;
        System.out.println("查询总条数为:"+ total+"........");
        SearchHit[] hits = responseHits.getHits();
        for (SearchHit hit : hits) {
            // 获取的事json格式的字符串
            String s = hit.getSourceAsString();
            // w我们可以把json转成对象操作
            HotelDoc hotelDoc = JSON.parseObject(s, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    }

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

全文检索查询 

match查询

精确查询

复合查询

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

和match_all相比只有内部,查询的类型和条件有所差异

我们发现有一部分解析的代码都一样,那么就可以抽取啦,快捷键command+option+m

@Test
    void esTest1() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        request.source().query(QueryBuilders.multiMatchQuery("如家","name", "brand"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }

    private void handleResponse(SearchResponse response) {
        SearchHits responseHits = response.getHits();
        long total = responseHits.getTotalHits().value;
        System.out.println("查询总条数为:"+ total+"........");
        SearchHit[] hits = responseHits.getHits();
        for (SearchHit hit : hits) {
            // 获取的事json格式的字符串
            String s = hit.getSourceAsString();
            // w我们可以把json转成对象操作
            HotelDoc hotelDoc = JSON.parseObject(s, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    }

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 演示boolquery

也就是说无论是boolquery、match、term、range。。查询,全都是用queryBuilders,而sorce返回的api是查询、分页、高亮等,是和query查询同级的

private void handleResponse(SearchResponse response) {
        SearchHits responseHits = response.getHits();
        long total = responseHits.getTotalHits().value;
        System.out.println("查询总条数为:"+ total+"........");
        SearchHit[] hits = responseHits.getHits();
        for (SearchHit hit : hits) {
            // 获取的事json格式的字符串
            String s = hit.getSourceAsString();
            // w我们可以把json转成对象操作
            HotelDoc hotelDoc = JSON.parseObject(s, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    }

    @Test
    void boolQueryTest() throws IOException {
        SearchRequest request = new SearchRequest("hotel");
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("name", "如家"));
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
        request.source().query(boolQuery);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

排序、分页、高亮

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

这里用链式编程只用写一个query,不然得下三个query查询 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

这么写多麻烦不是 ,模拟分页

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 高亮显示,注意高亮要对关键字高亮,不能用match_all

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 运行发现并没有高亮,这是因为高亮结果是与原始文档分离的,原始文档不可更改,高亮结果是与source同级的

获取soruce是用hit来获取的,同样获取高亮也用hit,获得结果是map,因为获取结果是个json对象,有key,有value,对应java就是map

将来我们就可以根据key去取value 了

取的高亮以后还要获取数组这一部分,就是value

fragment片段,其实就是取拿数组

拿到之后,就可以把结果set到我们的doc对象里了

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 value.getFragments()[0] 返回的其实是一个文本 text,它有一个方法string(),讲文本转成字符串

判断集合空spring里边是有工具类的CollectionUtils

private void handleResponse(SearchResponse response) {
        SearchHits responseHits = response.getHits();
        long total = responseHits.getTotalHits().value;
        System.out.println("查询总条数为:"+ total+"........");
        SearchHit[] hits = responseHits.getHits();
        for (SearchHit hit : hits) {
            // 获取的事json格式的字符串
            String s = hit.getSourceAsString();
            // w我们可以把json转成对象操作
            HotelDoc hotelDoc = JSON.parseObject(s, HotelDoc.class);

            /**
             * 处理高亮结果
             */
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                HighlightField value = highlightFields.get("name");
                if (value != null) {
                    String s1 = value.getFragments()[0].string();
                    hotelDoc.setName(s1);
                }
            }
            System.out.println(hotelDoc);
        }
    }

查看日志,就可以发现name属性”如家“ 已经带上高亮的标签了,至于高亮显示那就是前端的事了 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

黑马旅游案例

启动项目,查看搜搜网页,参数是这几个,key就是条件框输入的参数

酒店搜索和分页

这几个headers、payload 、preview 代表请求路径、参数、返回参数等信息

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

两个注意点:

1、controller接受的参数,可以用@RequestParam去单个接收,也可以我们后台自定义参数对象去接收用@RequestBody

2、返回条数和酒店数据,返回的对象我们也可以自定义实体类去接收 

定义参数对象 

@Data
public class RequestParams {
    private String key;
    private Integer page;
    private Integer size;
    private String sortBy;
}

定义返回对象,total和list,自定义构造方法,以后返回的时候直接new对象传递参数就可以了,更优雅

@Data
public class PageResult {
    private Long total;
    private List<HotelDoc> hotels;

    public PageResult() {

    }

    public PageResult(Long total, List<HotelDoc> hotels) {
        this.total = total;
        this.hotels = hotels;
    }
}

定义controller

@RestController
@RequestMapping("/hotel")
@Slf4j
public class HotelController {
    @Resource
    private IHotelService hotelService;

    /**
     * 我们这里用对象的接收方式,对象的话,要new一个前端传的实体类参数对象
     * 注意对象参数需要加注解@RequestBody,否则是接收不到参数的
     * @param requestParams
     * @return
     */
    @PostMapping("/list")
    public PageResult queryHotelListByKey(@RequestBody RequestParams requestParams){
        log.info("查询酒店信息,酒店入参_{}", JSON.toJSONString(requestParams));
        PageResult pageResult = hotelService.queryHotelListByParams(requestParams);
        log.info("获取酒店信息={}", JSON.toJSONString(pageResult));
        return pageResult;
    }
}

定义service实现

注意:基本类型参与运算不要用包装了,给它拆箱

@Resource
    private RestHighLevelClient client;
    @Override
    public PageResult queryHotelListByParams(RequestParams requestParams) {
        // 如果integer类型参与运算的话,就不要用包装类去接收,用它的基本类型接收,给它拆箱
        int size = requestParams.getSize();
        int from  = (requestParams.getPage()-1)*size;
        String key = requestParams.getKey();
        String sortBy = requestParams.getSortBy();
        try {
            // 准备DSL语句
            SearchRequest request = new SearchRequest("hotel");
            // 根据关键字搜索 做好健壮性判断
            if (null == key || "".equals(key)) {
                // 没有条件就全部查询
                request.source().query(QueryBuilders.matchAllQuery());
            } else {
                request.source().query(QueryBuilders.matchQuery("all", key));
            }
            // 分页查询
            request.source().from(from).size(size);
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            return handleResponse(response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private PageResult handleResponse(SearchResponse response) {
        SearchHits hits = response.getHits();
        // 解析条数
        long total = hits.getTotalHits().value;
        // 解析查询结果 文档数组
        SearchHit[] hitsHits = hits.getHits();
        List<HotelDoc> hotels = new ArrayList<>();
        for (SearchHit hit : hitsHits) {
            String source = hit.getSourceAsString();
            // 将原始文档数据转成对象
            HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
            // 添加到list集合
            hotels.add(hotelDoc);
        }
        // 封装返回结果,用构造方法去接收,更优雅
        return new PageResult(total, hotels);
    }

逻辑成功实现了 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

酒店结果过滤

条件过滤

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 多条件查询用booleanQuery,原全文检索查询也放到boolQuery里,多个 条件用and都是且的关系

public PageResult queryHotelListByParams(RequestParams requestParams) {
        // 如果integer类型参与运算的话,就不要用包装类去接收,用它的基本类型接收,给它拆箱
        int size = requestParams.getSize();
        int from  = (requestParams.getPage()-1)*size;
        String key = requestParams.getKey();
        String sortBy = requestParams.getSortBy();
        String brand = requestParams.getBrand();
        String city = requestParams.getCity();
        String starName = requestParams.getStarName();
        Integer maxPrice = requestParams.getMaxPrice();
        Integer minPrice = requestParams.getMinPrice();
        try {
            SearchRequest request = new SearchRequest("hotel");



            // option +command + m 封装一下 boolQuery
            BoolQueryBuilder boolQuery = buildQUeryBool(key, brand, city, starName, maxPrice, minPrice);
            request.source().query(boolQuery);




            // 分页查询
            request.source().from(from).size(size);
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            return handleResponse(response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
private BoolQueryBuilder buildQUeryBool(String key, String brand, String city, String starName, Integer maxPrice, Integer minPrice) {
        BoolQueryBuilder boolQuery = new BoolQueryBuilder();
        // 关键字搜索
        // 根据关键字搜索 做好健壮性判断
        if (null == key || "".equals(key)) {
            // 没有条件就全部查询
            boolQuery.must(QueryBuilders.matchAllQuery());
        } else {
            boolQuery.must(QueryBuilders.matchQuery("all", key));
        }
        // 过滤条件
        if (city != null && !"".equals(city)) {
            boolQuery.filter(QueryBuilders.termQuery("city", city));
        }
        // 品牌条件
        if (brand != null && !"".equals(brand)) {
            boolQuery.filter(QueryBuilders.termQuery("brand", brand));
        }
        // 星级
        if (starName != null && !"".equals(starName)) {
            boolQuery.filter(QueryBuilders.termQuery("starName", starName));
        }
        // 价格
        if (maxPrice != null && minPrice != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("price").gt(minPrice).lt(maxPrice));
        }
        return boolQuery;
    }

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

我周边的酒店

点击地图定位,显示我附近的酒店功能,并且有距离我多远多少km的功能

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

 es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

代码添加完后发现没有距离 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

代码如下,注意:查询、分页、高亮、排序、都是同级别的,都是source.出来的,不要写到一层去

里边有个sort值,这个值就是距离,这个sort 和我们的source是同级别的,可以用hit点出来,是个数组,将来有可能根据多个字段排序 

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

修改代码,在解析的代码里加上距离的操作就可以了

SearchHits hits = response.getHits();
        // 解析条数
        long total = hits.getTotalHits().value;
        // 解析查询结果 文档数组
        SearchHit[] hitsHits = hits.getHits();
        List<HotelDoc> hotels = new ArrayList<>();
        for (SearchHit hit : hitsHits) {
            String source = hit.getSourceAsString();
            // 将原始文档数据转成对象
            HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);




            // 修改代码,获取sort值 添加到hotelDoc里
            Object[] sortValues = hit.getSortValues();
            if (sortValues.length>0) {
                Object sortValue = sortValues[0];
                // 添加距离
                hotelDoc.setDistance(sortValue);
            }



            // 添加到list集合
            hotels.add(hotelDoc);
        }
        // 封装返回结果,用构造方法去接收,更优雅
        return new PageResult(total, hotels);

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎 以上按照距离排序,我附近的酒店功能就实现了

酒店竞价排名

就是该算分了,谁掏钱,我让谁制顶,并且有个广告的标识

isAD就广告的缩写AD

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

索引库文档修改内容添加isAD字段为true 就是打了广告了 


POST /hotel/_update/36934
{
  "doc" : {
    "isAD" : true
  }
}

POST /hotel/_update/395702
{
  "doc" : {
    "isAD" : true
  }
}
POST /hotel/_update/395434
{
  "doc" : {
    "isAD" : true
  }
}

算分函数默认是相乘的关系

es分词查询精确匹配,微服务,elasticsearch,大数据,搜索引擎

  修改代码如下文章来源地址https://www.toymoban.com/news/detail-793829.html

private void buildQueryBool(String key, String brand, String city, String starName, Integer maxPrice, Integer minPrice, RequestParams requestParams, SearchRequest request) {
        BoolQueryBuilder boolQuery = new BoolQueryBuilder();
        // 关键字搜索
        // 根据关键字搜索 做好健壮性判断
        if (null == key || "".equals(key)) {
            // 没有条件就全部查询
            boolQuery.must(QueryBuilders.matchAllQuery());
        } else {
            boolQuery.must(QueryBuilders.matchQuery("all", key));
        }
        // 过滤条件
        if (city != null && !"".equals(city)) {
            boolQuery.filter(QueryBuilders.termQuery("city", city));
        }
        // 品牌条件
        if (brand != null && !"".equals(brand)) {
            boolQuery.filter(QueryBuilders.termQuery("brand", brand));
        }
        // 星级
        if (starName != null && !"".equals(starName)) {
            boolQuery.filter(QueryBuilders.termQuery("starName", starName));
        }
        // 价格
        if (maxPrice != null && minPrice != null) {
            boolQuery.filter(QueryBuilders.rangeQuery("price").gt(minPrice).lt(maxPrice));
        }

        // 算分控制,以前用的是boolQuery,现在不可以了,boolQuery 是用来做算分的原始查询,现在是用functionScoreQuery
        // 两个参数,第一个是接收原始查询(将来影响算分),
        // 第二个是接收数组 就是算分函数 new FilterFunctionBuilder[] 数组,因为是内部类,所以new的时候就会用xxx.的方式了
        FunctionScoreQueryBuilder functionScoreQueryBuilder =
                // 构建FunctionScore
                QueryBuilders.functionScoreQuery(
                // 原始查询,用来做相关性算分的查询
                boolQuery,
                // functionScore的一个数组
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        // 其中的一个具体的functionScore元素
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                // boolean 类型也用term 过滤条件
                                QueryBuilders.termQuery("isAD", true),
                                // 算分函数
                                ScoreFunctionBuilders.weightFactorFunction(100)
                        )
        });
        // 这个结果将来就要放到source里去了
        request.source().query(functionScoreQueryBuilder);
    }

到了这里,关于第七章-分布式搜索引擎-ES:全文查询、分词查询、精确查询、地理坐标查询、组合查询(bool、funtion_score)以及RestApi的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 分布式搜索引擎--认识

    elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 。 elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域。 而elasticsearch是elastic stack的核

    2024年01月18日
    浏览(44)
  • 【分布式搜索引擎02】

    elasticsearch的查询依然是基于JSON风格的DSL来实现的。 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有 :查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询 :利用分词器对用户输入内容分词,然后去倒排索

    2024年02月01日
    浏览(43)
  • 微信小程序(第七章)- 搜索框的实现

    外部容器i 内部容器 两者关系:外部容器包裹内部容器,而且内部容器正好在we外部容器的居中(水平垂直居中)位置。 可在微信小程序中使用view,可以在view里面定义内容。 wxml文件 - html文件 wxss文件 - css文件 js文件 -js文件 json文件 - 配置文件 删除index.wxml里面的demo(模板)代

    2024年02月09日
    浏览(54)
  • 【分布式搜索引擎es】

    elasticsearch最擅长的是 搜索 和 数据分析 。 查询文档 常见的查询类型包括: 查询所有 :查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询 :利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如: match_query multi_match_query 精确查询 :根据精确

    2024年02月10日
    浏览(47)
  • ElasticSearch分布式搜索引擎

    KuangStudy ElasticSearch学习视频:狂神说ElasticSearch教程 1、官网 Elaticsearch ,简称为es,es是一个开源的 高扩展 的 分布式全文检索引擎 ,它可以近乎 实时的存储 、 检索数据; 本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据。es也使用java开发并使用

    2024年02月16日
    浏览(47)
  • 【分布式搜索引擎elasticsearch】

    什么是elasticsearch? 一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能 什么是elastic stack(ELK)? 是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在

    2024年02月10日
    浏览(51)
  • 分布式搜索引擎----elasticsearch

    目录 1、初识elasticsearch 1.1、什么是elasticsearch 1.2.ELK技术栈 2、正向索引和倒排索引 2.1、正向索引 2.2、倒排索引 2.3、正向索引和倒排索引的区别 3、elasticsearch中的概念理解 3.1、文档和字段 3.2、索引和映射 3.3、mysql与elasticsearch         elasticsearch是一款非常强大的开源搜索

    2024年02月11日
    浏览(54)
  • 分布式搜索引擎ES

    elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 例如: 在GitHub搜索代码 在电商网站搜索商品 在百度搜索答案 ELK技术栈 elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应

    2024年02月04日
    浏览(40)
  • 分布式搜索引擎elasticsearch(一)

    elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。 elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。 文档(document):每条数据就是一个文档 词条(term):文档按照语义分成的词语 倒排索引中包含两部分内容: 词条词

    2024年02月02日
    浏览(95)
  • 分布式搜索引擎ElasticSearch——基础

    什么是elasticsearch elasticsearch的发展 https://lucene.apache.org/ https://www.elastic.co/cn/ 正向索引和倒排索引 安装elasticsearch,kibana https://github.com/medcl/elasticsearch-analysis-ik 部署单点es 创建网络 因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络: 加载镜像

    2024年01月17日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包