【elasticsearch】搜索结果处理

news/2024/7/19 19:59:42 标签: elasticsearch, 大数据, java, 笔记, 搜索引擎, 全文检索

搜索结果处理

排序

elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。

java">GET /indexName/_search
{
	"query":{
		"match_all":{}
	},
	"sort":[
		{
			"FIELD":"desc" //排序字段和排序方式ASC、DESC  升序、降序
		}
	]
}
java">GET /indexName/_search
{
	"query":{
		"match_all":{}
	},
	"sort":[
		{
			"_geo_distance":{
                "FIELD":"纬度,经度",
                "order":"asc",
                "unit":"km"  //单位
            }
		}
	]
}

java">GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "score": {
        "order": "desc"
      },
      "price": {
        "order": "asc"
      }
    }
  ]
}

java">GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "_geo_distance": {
        "location": {
          "lat": 31,
          "lon": 121
        },
        "order": "asc",
        "unit": "km"
      }
    }
  ]
}

分页

elasticsearch默认情况下只返回top10的数据。而如果要查询更多的数据就需要修改分页参数了。

elasticsearch中通过修改from、size参数来控制要返回的分页结果

java">GET /hotel/_search
{
	"query":{
		"match_all":{}
	},
	"from":990, //分页开始的位置,默认为0
	"size":10, //期望获取的文档总数
	"sort":[
		{
			"price":"asc"
		}
	]
}
java">GET /hotel/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price":"asc"
    }
  ],
  "from": 0,
  "size": 20
}

深度分页问题

ES是分布式的,所以会面临深度分页问题。例如price排序后,获取from=990,size=10的数据:

高亮处理

高亮:就是在搜索结果中把搜索关键字突出显示。

java">GET /hotel/_search
{
	"query":{
		"match":{
			"FIELD":"TEXT"  //不能为match_all{} 因为高亮一定是对某个字段进行高亮
		}
	},
	"highlight":{
		"fields":{    //高亮的字段不止一个
			"FIELD":{
				"pre_tags":"<em>", //用于标记高亮字段的前置标签
				"post_tags":"</em>" //用于标记高亮字段的后置标签
			}
		}
	}
}
java">GET /hotel/_search
{
  "query": {
    "match": {
      "all": "如家"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "require_field_match": "false",
        "pre_tags": "<em>",
        "post_tags": "</em>"
      }
    }
  }
}

RestClient查询文档

match_all

java">    void testMatchAll() throws IOException {
        //1.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //2.准备DSL
        request.source().query(QueryBuilders.matchAllQuery());
        //3.发送请求
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        System.out.println(search);
    }

java">    void testMatchAll() throws IOException {
        //1.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //2.准备DSL
        request.source().query(QueryBuilders.matchAllQuery());
        //3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //解析结果
        SearchHits hits = response.getHits();
        //查询的总条数
        long total = hits.getTotalHits().value;
        System.out.println("一共搜索到 "+total+"数据");
        //查询hit数组
        SearchHit[] hits1 = hits.getHits();
        //遍历hit数组
        for(SearchHit hit : hits1){
            //得到source
            String json=hit.getSourceAsString();
            //反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            //打印
            System.out.println(hotelDoc);
            System.out.println();
        }
    }

全文检索查询

全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query部分。

multi_match:对多个字段进行查询。

java">    void testMulMatchAll() throws IOException {
        //创建request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        SearchSourceBuilder query = request.source().query(QueryBuilders.matchQuery("all", "如家"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
        System.out.println("搜索到的数据一共有:"+totalHits+"条");
        SearchHit[] hits1 = hits.getHits();
        for(SearchHit hit : hits1){
            String json = hit.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
            System.out.println();
        }
    }
java">    void testMulMatchAll1() throws IOException {
        //创建request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        SearchSourceBuilder query = request.source().query(QueryBuilders.multiMatchQuery("如家","brand","name","business"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
        System.out.println("搜索到的数据一共有:"+totalHits+"条");
        SearchHit[] hits1 = hits.getHits();
        for(SearchHit hit : hits1){
            String json = hit.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
            System.out.println();
        }
    }

精确查询

java">    void BooleanMatch() throws IOException {
        //1.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        //准备BooleanQuery
        BoolQueryBuilder boolQuery=QueryBuilders.boolQuery();
        //添加term
        boolQuery.must(QueryBuilders.termQuery("city","北京"));
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
        request.source().query(boolQuery);
        //发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
        System.out.println("搜索到的数据一共有:"+totalHits+"条");
        SearchHit[] hits1 = hits.getHits();
        for(SearchHit hit : hits1){
            String json = hit.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
            System.out.println();
        }
    }

排序和分页

java">    void PageTest() throws IOException {
        //1.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
       //准备query
        request.source().query(QueryBuilders.matchAllQuery());
        //排序
        request.source().sort("price", SortOrder.ASC);
        //分页
        request.source().from(0).size(5);
        //发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
        System.out.println("搜索到的数据一共有:"+totalHits+"条");
        SearchHit[] hits1 = hits.getHits();
        for(SearchHit hit : hits1){
            String json = hit.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
            System.out.println();
        }
    }

高亮

java">void HighLightTest() throws IOException {
    //1.准备Request
    SearchRequest request=new SearchRequest("hotel");
    //准备DSL
    //准备query
    request.source().query(QueryBuilders.matchQuery("all","如家"));
    //高亮
    request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
    //发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    SearchHits hits = response.getHits();
    TotalHits totalHits = hits.getTotalHits();
    System.out.println("搜索到的数据一共有:"+totalHits+"条");
    SearchHit[] hits1 = hits.getHits();
    for(SearchHit hit : hits1){
        String json = hit.getSourceAsString();
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
        System.out.println();
    }
}

但是为什么没有出现高亮呢?

java">    void HighLightTest1() throws IOException {
        //1.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        //准备query
        request.source().query(QueryBuilders.matchQuery("all","如家"));
        //高亮
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        //发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        TotalHits totalHits = hits.getTotalHits();
        System.out.println("搜索到的数据一共有:"+totalHits+"条");
        SearchHit[] hits1 = hits.getHits();
        for(SearchHit hit : hits1){
            //获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            //根据字段名获取高亮结果
            HighlightField highlightField = highlightFields.get("name");
            if(highlightField!=null){
                //获取高亮值
                String string = highlightField.getFragments()[0].string();
                System.out.println(string);
            }
        }
    }

加粗样式


http://www.niftyadmin.cn/n/5392434.html

相关文章

成功解决No module named ‘skimage‘(ModuleNotFoundError)

成功解决No module named ‘skimage’(ModuleNotFoundError) &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望得到您…

PAT (Basic Level) Practice | 编程团体赛

目录 输入格式输出格式输入样例输出样例Code比较推荐这个 编程团体赛的规则为&#xff1a;每个参赛队由若干队员组成&#xff1b;所有队员独立比赛&#xff1b;参赛队的成绩为所有队员的成绩和&#xff1b;成绩最高的队获胜。 现给定所有队员的比赛成绩&#xff0c;请你编写程序…

Spring中关于事务的一些方方面面

事务隔离级别&#xff1a; 先了解一些事务隔离级别有哪些&#xff1a; 未提交读(Read Uncommitted)&#xff1a; 允许脏读&#xff0c;也就是可能读取到其他会话中未提交事务修改的数据 提交读(Read Committed)&#xff1a; 只能读取到已经提交的数据。Oracle等多数数据库默…

开源工具和框架

目录 开源工具和框架 一、 开源工具和框架 二、开源工具和框架在现代软件开发中的角色 1、基础设施建设&#xff1a; 2、开发效率提升&#xff1a; 3、代码质量保障&#xff1a; 4、技术创新&#xff1a; 三、广泛使用的开源项目分析 3.1、Linux 3.2、Git 3.3、Docke…

线性代数:向量组的秩

目录 回顾“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2 矩阵的“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2

【Vue3】toRefs和toRef在reactive中的一些应用

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Ubuntu18.4桌面版安装并配置apt update与远程访问

1、无脑直接一步步安装即可 2、安装完成后与服务器版不同的是 服务器版(参照系统安装博客)通过选项安装openssh,桌面版啊需要通过 apt install openssh-server 进行安装 ----小插曲--- 如果使用apt install openssh-server 时 报错 无法解析ip 那么是由于未配置DNS 配置为1…

飞天使-k8s知识点23-kubernetes实操8-数据存储1

文章目录 持久化存储的必要EmptyDirHostPathNFS 持久化存储的必要 Volume是Pod中能够被多个容器访问的共享目录&#xff0c;它被定义在Pod上&#xff0c;然后被一个Pod里的多个容器挂载到具体的文件目录下&#xff0c;kubernetes通过Volume实现同一个Pod中不同容器之间的数据共…