IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 131.ElasticSearch(五):springboot整合es -> 正文阅读

[大数据]131.ElasticSearch(五):springboot整合es

我们前两章有写过整合es教程,但是那是使用spring data实现的,只能实现简单的es语句,复杂的语句我们推荐使用springboot

一、基本操作的实现

1.创建项目

?

2.添加依赖

项目目录如下:

?????????

上述搭建好项目后,添加json和es依赖

 <!--json-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.6.1</version>
        </dependency>

?3.编写eneity

JobDetail:

package com.xupeng.es.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/8/17 16:05]
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class JobDetail {
	private Long id;

	private String name;

	private int age;

	private String street;
}

4.编写config

ElasticSearchConfig:

package com.xupeng.es.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/8/17 16:02]
 */
@Configuration
public class ElasticSearchConfig {
	@Bean
	public RestHighLevelClient restHighLevelClient(){
		RestClientBuilder restClientBuilder = RestClient.builder(
				//如果是集群这里有多个HttpHost
				new HttpHost("192.168.210.149", 9200, "http")
		);
		RestHighLevelClient restHighLevelClient = new RestHighLevelClient(restClientBuilder);
		return restHighLevelClient;
	}
}

5.编写工具类和测试类

EsApplicationTests:

package com.xupeng.es;

import com.alibaba.fastjson.JSONObject;
import com.xupeng.es.entity.JobDetail;
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.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
class EsApplicationTests {

	//索引库名字
	private static final String JOB_IDX = "job_index";

	@Autowired
	private RestHighLevelClient restHighLevelClient;

	/**
	 * 新增
	 * @param jobDetail
	 * @throws IOException
	 */
	public void add(JobDetail jobDetail) throws IOException {
		//1.构建IndexRequest对象,用来描述ES发起请求的数据
		IndexRequest indexRequest = new IndexRequest(JOB_IDX);

		//2.设置文档ID
		indexRequest.id(jobDetail.getId().toString());

		//3.将实体对象转化为JSON
		String json = JSONObject.toJSONString(jobDetail);

		//4.使用IndexRequest.source方法设置文档数据,并设置请求的数据为json格式
		indexRequest.source(json, XContentType.JSON);

		//5.使用restHighLevelClient调用index方法发起请求,将一个文档添加到索引中
		restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);

	}

	/**
	 * 根据ID查找
	 * @param id
	 * @return
	 * @throws IOException
	 */
	public JobDetail findById(long id) throws IOException {
		//1.构建GetRequest
		GetRequest getRequest = new GetRequest(JOB_IDX, id + "");

		//2.使用restHighLevelClient.get发送GetRequest请求,并获取到es服务器的响应
		GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);

		//3.将es相应响应的数据转换为json字符串
		String json = getResponse.getSourceAsString();

		//4.将json转换为对象
		JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

		//5.记得,单独设置ID
		jobDetail.setId(id);

		return jobDetail;
	}

	/**
	 * 更新
	 * @param jobDetail
	 * @throws IOException
	 */
	public void update(JobDetail jobDetail) throws IOException {
		GetRequest getRequest = new GetRequest(JOB_IDX, jobDetail.getId().toString());
		boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);

		if (exists) {
			UpdateRequest updateRequest = new UpdateRequest(JOB_IDX, jobDetail.getId().toString());
			updateRequest.doc(JSONObject.toJSONString(jobDetail), XContentType.JSON);
			restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
		}
	}

	/**
	 * 删除
	 * @param id
	 * @throws IOException
	 */
	public void deleteById(long id) throws IOException {
		DeleteRequest deleteRequest = new DeleteRequest(JOB_IDX, id + "");
		restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
	}

	public List<JobDetail> searchByKeywords(String keywords) throws IOException {
		//1.构建SearchRequest检索请求
		SearchRequest searchRequest = new SearchRequest(JOB_IDX);

		//2.创建SearchSourceBuilder专门用于构建查询条件
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

		//3.构建一个查询条件,并配置到SearchSourceBuilder
		MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "name","street");
		searchSourceBuilder.query(multiMatchQueryBuilder);

		//4.调用searchRequest.source将查询条件设置到检所请求
		searchRequest.source(searchSourceBuilder);

		//5.执行restHighLevelClient.search发起请求
		SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		SearchHit[] hitArray = searchResponse.getHits().getHits();

		//6.遍历结果
		ArrayList<JobDetail> jobDetailArrayList = new ArrayList<JobDetail>();
		for (SearchHit documentFields : hitArray) {
			String json = documentFields.getSourceAsString();
			JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

			jobDetail.setId(Long.parseLong(documentFields.getId()));
			jobDetailArrayList.add(jobDetail);
		}

		return jobDetailArrayList;
	}

	public Map<String, Object> searchByPage(String keywords, int pageNum, int pageSize) throws IOException {
		//1.构建SearchRequest检索请求
		SearchRequest searchRequest = new SearchRequest(JOB_IDX);

		//2.创建SearchSourceBuilder专门用于构建查询条件
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

		//3.构建一个查询条件,并配置到SearchSourceBuilder
		MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "name", "street");
		searchSourceBuilder.query(multiMatchQueryBuilder);

		//用于分页
		searchSourceBuilder.size(pageSize);
		searchSourceBuilder.from((pageNum - 1) * pageSize);

		//4.调用searchRequest.source将查询条件设置到检所请求
		searchRequest.source(searchSourceBuilder);

		//5.执行restHighLevelClient.search发起请求
		SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		SearchHit[] hitArray = searchResponse.getHits().getHits();

		//6.遍历结果
		ArrayList<JobDetail> jobDetailArrayList = new ArrayList<JobDetail>();
		for (SearchHit documentFields : hitArray) {
			String json = documentFields.getSourceAsString();
			JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

			jobDetail.setId(Long.parseLong(documentFields.getId()));
			jobDetailArrayList.add(jobDetail);
		}

		//结果封装到map中
		long totalNum = searchResponse.getHits().getTotalHits().value;
		HashMap map = new HashMap();
		map.put("total", totalNum);
		map.put("content", jobDetailArrayList);
		return map;
	}

	public Map<String, Object> searchByLhPage(String keywords, String scrollId, int pageSize) throws IOException {
		SearchResponse searchResponse = null;

		//1.构建SearchRequest检索请求
		SearchRequest searchRequest = new SearchRequest(JOB_IDX);

		//2.创建SearchSourceBuilder专门用于构建查询条件
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

		//3.构建一个查询条件,并配置到SearchSourceBuilder
		MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keywords, "name", "street");
		searchSourceBuilder.query(multiMatchQueryBuilder);

		//设置高亮
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.field("name");
		highlightBuilder.field("street");
		highlightBuilder.preTags("<font color='red'>");
		highlightBuilder.postTags("</font>");

		//给请求设置高亮
		searchSourceBuilder.highlighter(highlightBuilder);

		//用于分页
		searchSourceBuilder.size(pageSize);

		//4.调用searchRequest.source将查询条件设置到检所请求
		searchRequest.source(searchSourceBuilder);

		//5.执行restHighLevelClient.search发起请求
		searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
		SearchHit[] hitArray = searchResponse.getHits().getHits();

		//6.遍历结果
		ArrayList<JobDetail> jobDetailArrayList = new ArrayList<JobDetail>();
		for (SearchHit documentFields : hitArray) {
			String json = documentFields.getSourceAsString();
			JobDetail jobDetail = JSONObject.parseObject(json, JobDetail.class);

			jobDetail.setId(Long.parseLong(documentFields.getId()));
			jobDetailArrayList.add(jobDetail);

			//设置高亮的一些文本到实体类中
			Map<String, HighlightField> highlightFieldMap = documentFields.getHighlightFields();
			HighlightField nameHL = highlightFieldMap.get("name");
			HighlightField streetHl = highlightFieldMap.get("street");

			if (nameHL != null) {
				Text[] fragments = nameHL.getFragments();
				StringBuilder builder = new StringBuilder();
				for (Text text : fragments) {
					builder.append(text);
				}
				jobDetail.setName(builder.toString());
			}
			if (streetHl != null) {
				Text[] fragments = streetHl.getFragments();
				StringBuilder builder = new StringBuilder();
				for (Text text : fragments) {
					builder.append(text);
				}
				jobDetail.setStreet(builder.toString());
			}
		}

		//结果封装到map中
		long totalNum = searchResponse.getHits().getTotalHits().value;
		HashMap map = new HashMap();
		map.put("total", totalNum);
		map.put("content", jobDetailArrayList);
		return map;
	}

	public void close() throws IOException {
		restHighLevelClient.close();
	}


	//-------------------------------------------------------------------------------------
	//上述方法测试


	@Test
	public void doAdd() throws IOException {
		JobDetail jobDetail = new JobDetail();
		jobDetail.setId(22L);
		jobDetail.setName("2b2");
		jobDetail.setAge(22);
		jobDetail.setStreet("22");
		add(jobDetail);

	}

	@Test
	public void doFindById() throws IOException {
		System.out.println(findById(11));
	}

	@Test
	public void doUpdate() throws IOException {
		JobDetail jobDetail = findById(11);
		jobDetail.setName("bbb");
		update(jobDetail);
		System.out.println(findById(11));
	}

	@Test
	public void doSearch() throws IOException {
		List<JobDetail> jobDetailList = searchByKeywords("bbb");
		for(JobDetail jobDetail:jobDetailList){
			System.out.println(jobDetail);
		}
	}

	@Test
	public void doSearchHL() throws IOException {
		Map<String,Object> map = searchByLhPage("bbb","",10);
		System.out.println(map);
	}

}

二、模拟京东的后端实现

1.我们先来给es建表

常规字段 + 属性字段,其中属性字段为数组

PUT product_db
{
  "mappings": {
    "properties": {
      "id":{
        "type": "long"
      },
     "name":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "keywords":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "subTitle":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
       "putawayDate":{
        "type": "date"
      },
       "price":{
        "type": "double"
      },
       "promotionPrice":{
        "type": "keyword"
      },
      "originalPrice":{
        "type": "keyword"
      },
      "pic":{
        "type": "keyword"
      },
      "sale":{
        "type": "long"
      },
      "hasStock":{
        "type": "boolean"
      },
      "brandId":{
        "type": "long"
      },
      "brandName":{
        "type": "keyword"
      },
      "brandImg":{
        "type": "keyword"
      },
      "categoryId":{
        "type": "long"
      },
      "categoryName":{
        "type": "keyword"
      },
      "attrs":{
        "type": "nested",
        "properties": {
          "attrId":{
            "type":"long"
          },
          "attrName":{
            "type":"keyword"
          },
          "attrValue":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

2.设置数据

PUT /product_db/_doc/1
{
  "id":"1",
  "name":"小米11手机",
  "keywords":"小米手机",
  "subTitle":"小米智慧全面屏手机,双卡双待",
  "putawayDate":"2021-04-01",
  "price":"3999",
  "promotionPrice":"2999",
  "originalPrice":"5999",
  "pic":"xiaomi.jpg",
  "sale":999,
  "hasStock":true,
  "brandId":"1",
  "brandName":"小米",
  "brandImg":"xiaomibrand.jpg",
  "categoryId":"1",
  "categoryName":"手机通讯",
  "attrs":[
    {
      "attrId":1,
      "attrName":"cpu",
      "attrValue":"2核"
    },
    {
       "attrId":2,
      "attrName":"颜色",
      "attrValue":"黑色"
    }
    ]
  
}


PUT /product_db/_doc/2
{
  "id":"2",
  "name":"苹果手机",
  "keywords":"苹果手机",
  "subTitle":"苹果5G手机",
  "putawayDate":"2021-04-01",
  "price":"4999",
  "promotionPrice":"2999",
  "originalPrice":"5999",
  "pic":"pingguo.jpg",
  "sale":999,
  "hasStock":true,
  "brandId":"1",
  "brandName":"苹果",
  "brandImg":"pingguobrand.jpg",
  "categoryId":"1",
  "categoryName":"手机通讯",
  "attrs":[
    {
      "attrId":3,
      "attrName":"外壳",
      "attrValue":"塑料"
    },
    {
       "attrId":2,
      "attrName":"颜色",
      "attrValue":"白色"
    }
    ]
  
}

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-08-18 12:46:21  更:2021-08-18 12:48:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:47:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码