精华内容
参与话题
问答
  • springboot集成ElasticsearchBboss调用Elasticsearch的案例分享
  • 最近项目用到elasticsearch,结合官方提供的RestHighLevelClient使用,这里记录下项目整合实践的过程,包括创建索引、增删改、搜索以及批量操作等。 首先,简单的介绍下: elasticsearch是一个实时的分布式搜索...

    最近项目用到elasticsearch,结合官方提供的RestHighLevelClient使用,这里记录下项目整合实践的过程,包括创建索引、增删改、搜索以及批量操作等。

    首先,简单的介绍下:

    elasticsearch是一个实时的分布式搜索引擎,基于Lucene开发,它可以快速的存储和搜索海量数据,同时提供RestAPI操作接口,可以说开箱即用。

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    补充笔记:

    ElasticSearch架构相关概念

    1、cluster(集群)

    一个集群由一个或多个节点组成,持有全部的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,默认是elasticsearch ,通过配置文件elasticsearch.yml中的cluster.name来配置,节点通过配置集群的名字来加入指定的集群。

    2、node节点

    节点是一个运行的ES实例,存储数据并且参与集群的索引和搜索功能, ⼀个节点也是由⼀个名字来标识的,通过node.name来配置。

    3、shard & replica分片和副本

    一个节点下可以有多个分片,分片分为:主分片、副本分片。

    主分片,用来解决数据水平扩展的问题,一个索引的所有数据存储在不同的主分片中(每个主分片存储一部分数据,主分片分布在不同的节点上),一个索引的主分片数量只能在创建索引时指定,指定后无法修改,除非重新构建索引(即reindex

    副本分片,用来解决数据高可用的问题,每一个一个副本分片都是一个主分片的拷贝,其数量可以动态调整,通过增加副本分片可以提升系统读性能

    ElasticSearch数据相关概念

    1、indices(索引库)

    indicesindex的复数形式,即多个索引,可以想象成MySQL中的Databases(数据库)

    2、type(索引类型

    个索引库下可以有多个不同的索引类型,例如用户索引、商品索引、订单索引,就像MySQLTable(数据表)

    3、document(文档)

    存入索引类型中的原始数据,例如一条用户信息,就是一个文档,可以想象成MySQL中的row(行)

    4、field字段

    文档中的属性,例如商品的Id、商品名称、商品状态等,就像MySQL中的column

    RestHightLevelClient

    RestHighLevelClient也称Java High Level REST Client,是官方提供的Java客户端库,适用于高版本的ElasticSearch,主要提供一系列REST API方便用户调用。注意RestHighLevelClient版本需要大于或等于ElasticSearch的版本,因为某些API请求新加了一些字段可能会导致兼容问题。

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面是安装准备:

    这里用的是elasticsearch-6.4.0,在windows下搭建伪集群,下载elasticsearch-6.4.0.zip压缩包,下载地址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.4.0.zip

    下载完成后解压elasticsearch-6.4.0.zip,复制一份得到两个文件夹,然后分别重命名为elasticsearch-6.4.0_1,elasticsearch-6.4.0_2,然后修改两个文件夹下的配置文件,/config/elasticsearch.yml:

    # 第一个节点配置
    # 集群名称
    cluster.name: es
    # 节点名称
    node.name: node-0
    # 是否参与master节点竞选
    node.master: true
    # 访问地址
    network.host: 127.0.0.1
    # 访问端口
    http.port: 9200
    # 内部通讯端口
    transport.tcp.port: 9300
    # 集群节点配置,注意,这里是IP:内部通讯端口,多个用,隔开
    discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301"]
    # 最少竞选master节点个数
    
    # 第二个节点配置
    # 集群名称
    cluster.name: es
    # 节点名称
    node.name: node-1
    # 是否参与master节点竞选
    node.master: true
    # 访问地址
    network.host: 127.0.0.1
    # 访问端口
    http.port: 9201
    # 内部通讯端口
    transport.tcp.port: 9301
    # 集群节点配置,注意,这里是IP:内部通讯端口,多个用,隔开
    discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300"]
    # 最少竞选master节点个数
    discovery.zen.minimum_master_nodes: 2

    在window环境下,直接启动/bin下的elasticsearch.bat即可启动,启动成功后访问http://127.0.0.1:9200会返回如下json信息:

    {
      "name" : "node-0",
      "cluster_name" : "es",
      "cluster_uuid" : "fYtHRgFjRJuUrmJNz8tA_g",
      "version" : {
        "number" : "6.4.0",
        "build_flavor" : "default",
        "build_type" : "tar",
        "build_hash" : "595516e",
        "build_date" : "2018-08-17T23:18:47.308994Z",
        "build_snapshot" : false,
        "lucene_version" : "7.4.0",
        "minimum_wire_compatibility_version" : "5.6.0",
        "minimum_index_compatibility_version" : "5.0.0"
      },
      "tagline" : "You Know, for Search"
    }

    接着下载Cerebro,这个是一款Elasticsearch监控工具,下载地址:

    https://github.com/lmenezes/cerebro/releases

    下载后解压,进入/bin文件夹下,启动cerebro.bat即可,访问http://127.0.0.1:9000,然后输入:http://127.0.0.1:9200,进入监控界面,如下:

    可以看到,集群环境已经成功搭建。

    接下来新建一个SpringBoot maven项目,添加elasticsearch依赖,这个因为spring-data-elasticsearch暂不支持elasticsearch6.0以上版本,所以笔者用的是elasticsearch提供的RestHighLevelClient,pom文件如下:

    <properties>
    	<java.version>1.8</java.version>
    	<elasticsearch.version>6.4.3</elasticsearch.version>
    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <parent>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-parent</artifactId>
    	<version>1.5.3.RELEASE</version>
    </parent>
    
    <dependencies>
    
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-web</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-test</artifactId>
    	</dependency>
    
    	<dependency>
    		<groupId>org.elasticsearch</groupId>
    		<artifactId>elasticsearch</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.elasticsearch.client</groupId>
    		<artifactId>elasticsearch-rest-high-level-client</artifactId>
    		<version>6.4.3</version>
    	</dependency>
    
    	<dependency>
    		<groupId>com.alibaba</groupId>
    		<artifactId>fastjson</artifactId>
    		<version>1.2.54</version>
    	</dependency>
    
    	<dependency>
    		<groupId>junit</groupId>
    		<artifactId>junit</artifactId>
    		<scope>test</scope>
    	</dependency>
    </dependencies>

    添加启动类EsApp,如下:

    package com.es;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class EsApp {
    	public static void main(String[] args) {
    		SpringApplication.run(EsApp.class, args);
    	}
    }

    添加elasticsearch配置类EsConfiguration,主要用来构建RestHighLevelClient客户端,如下 :

    package com.es.config;
    
    import java.util.ArrayList;
    
    import org.apache.http.HttpHost;
    import org.apache.http.client.config.RequestConfig.Builder;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
    import org.elasticsearch.client.RestClientBuilder.RequestConfigCallback;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class EsConfiguration {
    
    	private static String hosts = "127.0.0.1"; // 集群地址,多个用,隔开
    	private static int port = 9200; // 使用的端口号
    	private static String schema = "http"; // 使用的协议
    	private static ArrayList<HttpHost> hostList = null;
    
    	private static int connectTimeOut = 1000; // 连接超时时间
    	private static int socketTimeOut = 30000; // 连接超时时间
    	private static int connectionRequestTimeOut = 500; // 获取连接的超时时间
    
    	private static int maxConnectNum = 100; // 最大连接数
    	private static int maxConnectPerRoute = 100; // 最大路由连接数
    
    	static {
    		hostList = new ArrayList<>();
    		String[] hostStrs = hosts.split(",");
    		for (String host : hostStrs) {
    			hostList.add(new HttpHost(host, port, schema));
    		}
    	}
    
    	@Bean
    	public RestHighLevelClient client() {
    		RestClientBuilder builder = RestClient.builder(hostList.toArray(new HttpHost[0]));
    		// 异步httpclient连接延时配置
    		builder.setRequestConfigCallback(new RequestConfigCallback() {
    			@Override
    			public Builder customizeRequestConfig(Builder requestConfigBuilder) {
    				requestConfigBuilder.setConnectTimeout(connectTimeOut);
    				requestConfigBuilder.setSocketTimeout(socketTimeOut);
    				requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
    				return requestConfigBuilder;
    			}
    		});
    		// 异步httpclient连接数配置
    		builder.setHttpClientConfigCallback(new HttpClientConfigCallback() {
    			@Override
    			public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
    				httpClientBuilder.setMaxConnTotal(maxConnectNum);
    				httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
    				return httpClientBuilder;
    			}
    		});
    		RestHighLevelClient client = new RestHighLevelClient(builder);
    		return client;
    	}
    
    }

    添加测试bean类Tests,如下:

    package com.es.bean;
    
    public class Tests {
    	
    	private Long id;
    
    	private String name;
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	@Override
    	public String toString() {
    		return "Tests [id=" + id + ", name=" + name + "]";
    	}
    	
    }
    

    最后添加测试类EsAppTest,然后可以开始用RestHighLevelClient来对elasticsearch进行探索测试了,例如增加索引、增删改查以及批量操作,testIndex如下:

    package com.es;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
    import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
    import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
    import org.elasticsearch.action.bulk.BulkRequest;
    import org.elasticsearch.action.bulk.BulkResponse;
    import org.elasticsearch.action.delete.DeleteRequest;
    import org.elasticsearch.action.delete.DeleteResponse;
    import org.elasticsearch.action.get.GetRequest;
    import org.elasticsearch.action.get.GetResponse;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.index.IndexResponse;
    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.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.elasticsearch.index.query.BoolQueryBuilder;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.SearchHits;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
    import org.junit.BeforeClass;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import com.alibaba.fastjson.JSON;
    import com.es.bean.Tests;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = { EsApp.class }) // 指定启动类
    public class EsAppTest {
    
    	@Autowired
    	private RestHighLevelClient client;
    
    	public static String INDEX_TEST = null;
    	public static String TYPE_TEST = null;
    	public static Tests tests = null;
    	public static List<Tests> testsList = null;
    
    	@BeforeClass
    	public static void before() {
    		INDEX_TEST = "index_test"; // 索引名称
    		TYPE_TEST = "type_test"; // 索引类型
    		testsList = new ArrayList<>();
    		for (int i = 0; i < 100; i++) {
    			tests = new Tests();
    			tests.setId(Long.valueOf(i));
    			tests.setName("this is the test " + i);
    			testsList.add(tests);
    		}
    	}
    	
    	@Test
    	public void testIndex() throws IOException {
    		// 各种操作
    	}
    
    }
    

    第一步,新建索引,我们在testIndex下添加一个方法createIndex来创建索引,如下:

    /**
     * 创建索引
     * @param index
     * @throws IOException
     */
    public void createIndex(String index) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
        CreateIndexResponse createIndexResponse = client.indices().create(request,     RequestOptions.DEFAULT);
        System.out.println("createIndex: " + JSON.toJSONString(createIndexResponse));
    }

    但是创建索引之前我们要判断索引是不是已经存在了,不存在我们才创建,所以再添加一个判断的方法existsIndex,如下:

    /**
     * 判断索引是否存在
     * @param index
     * @return
     * @throws IOException
     */
    public boolean existsIndex(String index) throws IOException {
    	GetIndexRequest request = new GetIndexRequest();
    	request.indices(index);
    	boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
    	System.out.println("existsIndex: " + exists);
    	return exists;
    }

    然后修改testIndex方法,增加如下代码:

    @Test
    public void testIndex() throws IOException {
    	// 判断是否存在索引
    	if (!existsIndex(INDEX_TEST)) {
    		// 不存在则创建索引
    		createIndex(INDEX_TEST);
    	}
    }

    运行下测试类,结果输出:existsIndex: true,因为笔者已经创建过索引了。

    接着是增加记录到elasticsearch,添加一个增加记录的方法add,如下:

    /**
     * 增加记录
     * @param index
     * @param type
     * @param tests
     * @throws IOException
     */
    public void add(String index, String type, Tests tests) throws IOException {
    	IndexRequest indexRequest = new IndexRequest(index, type, tests.getId().toString());
    	indexRequest.source(JSON.toJSONString(tests), XContentType.JSON);
    	IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
    	System.out.println("add: " + JSON.toJSONString(indexResponse));
    }

    同样的添加一个判断记录是否存在的方法exists,如下:

    	/**
    	 * 判断记录是都存在
    	 * @param index
    	 * @param type
    	 * @param tests
    	 * @return
    	 * @throws IOException
    	 */
    	public boolean exists(String index, String type, Tests tests) throws IOException {
    		GetRequest getRequest = new GetRequest(index, type, tests.getId().toString());
    		getRequest.fetchSourceContext(new FetchSourceContext(false));
    		getRequest.storedFields("_none_");
    		boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
    		System.out.println("exists: " + exists);
    		return exists;
    	}

    因为tests对象初始化好了,修改testIndex方法,如下:

    	@Test
    	public void testIndex() throws IOException {
    		// 判断是否存在索引
    		if (!existsIndex(INDEX_TEST)) {
    			// 不存在则创建索引
    			createIndex(INDEX_TEST);
    		}
    		// 判断是否存在记录
    		if (!exists(INDEX_TEST, TYPE_TEST, tests)) {
    			// 不存在增加记录
    			add(INDEX_TEST, TYPE_TEST, tests);
    		}
    	}

    笔者先用Cerebro把索引删除,执行输出如下:

    可以看到创建索引以及增加记录操作都成功了。

    接下来添加获取记录信息、更新记录信息、删除记录的方法,分别做测试,如下:

    	/**
    	 * 获取记录信息
    	 * @param index
    	 * @param type
    	 * @param id
    	 * @throws IOException
    	 */
    	public void get(String index, String type, Long id) throws IOException {
    		GetRequest getRequest = new GetRequest(index, type, id.toString());
    		GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
    		System.out.println("get: " + JSON.toJSONString(getResponse));
    	}
    
    	/**
    	 * 更新记录信息
    	 * @param index
    	 * @param type
    	 * @param tests
    	 * @throws IOException
    	 */
    	public void update(String index, String type, Tests tests) throws IOException {
    		tests.setName(tests.getName() + "updated");
    		UpdateRequest request = new UpdateRequest(index, type, tests.getId().toString());
    		request.doc(JSON.toJSONString(tests), XContentType.JSON);
    		UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
    		System.out.println("update: " + JSON.toJSONString(updateResponse));
    	}
    
    	/**
    	 * 删除记录
    	 * @param index
    	 * @param type
    	 * @param id
    	 * @throws IOException
    	 */
    	public void delete(String index, String type, Long id) throws IOException {
    		DeleteRequest deleteRequest = new DeleteRequest(index, type, id.toString());
    		DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
    		System.out.println("delete: " + JSON.toJSONString(response));
    	}

    同时还有搜索的方法search,如下:

    	/**
    	 * 搜索
    	 * @param index
    	 * @param type
    	 * @param name
    	 * @throws IOException
    	 */
    	public void search(String index, String type, String name) throws IOException {
    		BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
    		boolBuilder.must(QueryBuilders.matchQuery("name", name)); // 这里可以根据字段进行搜索,must表示符合条件的,相反的mustnot表示不符合条件的
    		// boolBuilder.must(QueryBuilders.matchQuery("id", tests.getId().toString()));
    		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    		sourceBuilder.query(boolBuilder);
    		sourceBuilder.from(0);
    		sourceBuilder.size(100); // 获取记录数,默认10
    		sourceBuilder.fetchSource(new String[] { "id", "name" }, new String[] {}); // 第一个是获取字段,第二个是过滤的字段,默认获取全部
    		SearchRequest searchRequest = new SearchRequest(index);
    		searchRequest.types(type);
    		searchRequest.source(sourceBuilder);
    		SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
    		System.out.println("search: " + JSON.toJSONString(response));
    		SearchHits hits = response.getHits();
    		SearchHit[] searchHits = hits.getHits();
    		for (SearchHit hit : searchHits) {
    			System.out.println("search -> " + hit.getSourceAsString());
    		}
    	}

    最后还有批量操作的方法bulk,如下:

    	/**
    	 * 批量操作
    	 * @throws IOException
    	 */
    	public void bulk() throws IOException {
    		// 批量增加
    		BulkRequest bulkAddRequest = new BulkRequest();
    		for (int i = 0; i < testsList.size(); i++) {
    			tests = testsList.get(i);
    			IndexRequest indexRequest = new IndexRequest(INDEX_TEST, TYPE_TEST, tests.getId().toString());
    			indexRequest.source(JSON.toJSONString(tests), XContentType.JSON);
    			bulkAddRequest.add(indexRequest);
    		}
    		BulkResponse bulkAddResponse = client.bulk(bulkAddRequest, RequestOptions.DEFAULT);
    		System.out.println("bulkAdd: " + JSON.toJSONString(bulkAddResponse));
    		search(INDEX_TEST, TYPE_TEST, "this");
    		
    		// 批量更新
    		BulkRequest bulkUpdateRequest = new BulkRequest();
    		for (int i = 0; i < testsList.size(); i++) {
    			tests = testsList.get(i);
    			tests.setName(tests.getName() + " updated");
    			UpdateRequest updateRequest = new UpdateRequest(INDEX_TEST, TYPE_TEST, tests.getId().toString());
    			updateRequest.doc(JSON.toJSONString(tests), XContentType.JSON);
    			bulkUpdateRequest.add(updateRequest);
    		}
    		BulkResponse bulkUpdateResponse = client.bulk(bulkUpdateRequest, RequestOptions.DEFAULT);
    		System.out.println("bulkUpdate: " + JSON.toJSONString(bulkUpdateResponse));
    		search(INDEX_TEST, TYPE_TEST, "updated");
    		
    		// 批量删除
    		BulkRequest bulkDeleteRequest = new BulkRequest();
    		for (int i = 0; i < testsList.size(); i++) {
    			tests = testsList.get(i);
    			DeleteRequest deleteRequest = new DeleteRequest(INDEX_TEST, TYPE_TEST, tests.getId().toString());
    			bulkDeleteRequest.add(deleteRequest);
    		}
    		BulkResponse bulkDeleteResponse = client.bulk(bulkDeleteRequest, RequestOptions.DEFAULT);
    		System.out.println("bulkDelete: " + JSON.toJSONString(bulkDeleteResponse));
    		search(INDEX_TEST, TYPE_TEST, "this");
    	}
    	

    再回过头来修改下testIndex方法,对上面的方法做下验证,如下:

    	@Test
    	public void testIndex() throws IOException {
    		// 判断是否存在索引
    		if (!existsIndex(INDEX_TEST)) {
    			// 不存在则创建索引
    			createIndex(INDEX_TEST);
    		}
    		// 判断是否存在记录
    		if (!exists(INDEX_TEST, TYPE_TEST, tests)) {
    			// 不存在增加记录
    			add(INDEX_TEST, TYPE_TEST, tests);
    		}
    		// 获取记录信息
    		get(INDEX_TEST, TYPE_TEST, tests.getId());
    		
    		// 更新记录信息
    		update(INDEX_TEST, TYPE_TEST, tests);
    		get(INDEX_TEST, TYPE_TEST, tests.getId());
    		
    		// 删除记录信息
    		delete(INDEX_TEST, TYPE_TEST, tests.getId());
    		get(INDEX_TEST, TYPE_TEST, tests.getId());
    		
    		// 批量操作
    		bulk();
    	}

    运行输出如下:

     

    参考:

    https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high.html

    代码:

    https://github.com/191720653/es

     

    展开全文
  • springboot elasticsearch

    2018-12-13 23:47:53
    springboot集成elasticsearch,maven引入pom.xml &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starte...

    elasticsearch首先人家是一个搜索引擎,性能很好。

    springboot集成elasticsearch,maven引入pom.xml

            <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>net.java.dev.jna</groupId>
    			<artifactId>jna</artifactId>
    			<scope>runtime</scope>
    		</dependency>

     

    application.properties

    spring.data.elasticsearch.cluster-name=elasticsearch
    spring.data.elasticsearch.cluster-nodes=localhost:9300

     

    有两种方法,一种是基于spring data Repository,一种是ElasticsearchTemplate。

    第一种demo:

    定义Repository

    package com.example.demo;
    
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldType;
    
    import java.io.Serializable;
    
    @Document(indexName = "test1",type = "test2")
    public class test implements Serializable {
    
        @Field()
        private int id;
    
        @Field(searchAnalyzer = "ik_smart",analyzer = "ik_smart")
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "test{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    

    @Field(searchAnalyzer = "ik_smart",analyzer = "ik_smart")这个是设置中文分词查询的

    比如说,我输入查找的词为大家好,会拆成大,家,好去查询

     

    test

    package com.example.demo;
    
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
    import org.springframework.data.elasticsearch.core.ResultsExtractor;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
    import org.springframework.data.querydsl.binding.QuerydslPredicateBuilder;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class DemoApplicationTests {
    
    	@Autowired
    	TestRepository testRepository;
    
    	@Autowired
    	ElasticsearchTemplate elasticsearchTemplate;
    
    	@Test
    	public void contextLoads() {
    		test t=new test();
    		t.setId(3);
    		t.setName("大鸡腿哦哦哦");
    		testRepository.save(t);
    	}
    
    	@Test
    	public void a(){
    		Iterable<test> iterable=testRepository.findAll();
    		for(test t:iterable){
    			System.out.println(t.getId()+" "+t.getName());
    		}
    	}
    
    
    
    }
    
    

    run,然后在浏览器输入http://localhost:9200/test1/_search

    {"took":232,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":3,"max_score":1.0,"hits":[{"_index":"test1","_type":"test2","_id":"2","_score":1.0,"_source":{"id":2,"name":"大家好啊 123"}},{"_index":"test1","_type":"test2","_id":"1","_score":1.0,"_source":{"id":1,"name":"dajitui"}},{"_index":"test1","_type":"test2","_id":"3","_score":1.0,"_source":{"id":3,"name":"大鸡腿哦哦哦"}}]}}

    期间插入很多个,方便测试

     

    第二种demo:

    package com.example.demo;
    
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
    import org.springframework.data.elasticsearch.core.ResultsExtractor;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
    import org.springframework.data.querydsl.binding.QuerydslPredicateBuilder;
    import org.springframework.test.context.junit4.SpringRunner;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class DemoApplicationTests {
    
    	@Autowired
    	TestRepository testRepository;
    
    	@Autowired
    	ElasticsearchTemplate elasticsearchTemplate;
    
    
    	@Test
    	public void b(){
    		NativeSearchQueryBuilder queryBuilder=new NativeSearchQueryBuilder();
    		queryBuilder.withIndices("test1");
    		queryBuilder.withTypes("test2");
    		String keyword="大";
    		queryBuilder.withHighlightFields(new HighlightBuilder.Field("name").preTags("<font style='color:red;'>").postTags("</font>"));
    		queryBuilder.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name",keyword)));
    
    		List<test> list=elasticsearchTemplate.query(queryBuilder.build(), new ResultsExtractor<List<test>>() {
    			@Override
    			public List<test> extract(SearchResponse searchResponse) {
    				List<test> list=new ArrayList<test>();
    
    				for(SearchHit hit:searchResponse.getHits()){
    					test t=new test();
    					t.setId(Integer.parseInt(hit.getId()));
    					t.setName(hit.getHighlightFields().get("name").fragments()[0].toString());
    					list.add(t);
    				}
    				return list;
    			}
    		});
    
    		for(test t:list){
    			System.out.println(t.toString());
    		}
    
    
    	}
    
    
    }
    
    

    执行结果:

    test{id=2, name='<font style='color:red;'>大</font>家好啊 123'}
    test{id=3, name='<font style='color:red;'>大</font>鸡腿哦哦哦'}

    看到中文分词了吗,还有高亮

    github:https://github.com/dajitui/springboot-elasticsearch

     

    还有涉及到索引构造方式

    可以使用mysql,或者mongodb的数据同步到elasticsearch,可以使用第三方工具

    mysql:elasticsearch-jdbc

    mongodb:mongo-connector

    展开全文
  • springboot elasticSearch JPA

    2019-10-29 14:39:23
    ElasticsearchOperations ElasticsearchTemplate ...Spring Elasticsearch data 乐观锁并发控制 Spring Elasticsearch data 乐观锁并发控制 https://www.jianshu.com/p/56ff0d68e03f spring-data-el...
        

    ElasticsearchOperations
    ElasticsearchTemplate

    增删改查

    条件查询
    聚合查询
    分页查询

    并发控制

    Spring Elasticsearch data 乐观锁并发控制

    Spring Elasticsearch data 乐观锁并发控制
    https://www.jianshu.com/p/56ff0d68e03f

    spring-data-elasticsearch 并发修改

    spring-data-elasticsearch 并发修改
    加锁Redis分布式锁

    展开全文
  • SpringBoot ElasticSearch elk

    2019-05-20 14:35:00
    docker下载并启动ElasticSearch # 下载 docker pull docker.io/elasticsearch:6.5.1 # 安装 docker run -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -d -p 9200:9200 -p 9300:9300 --name myE...

     谁在使用ELK

    维基百科, github都使用 ELK

    docker下载并启动ElasticSearch


    #
    下载 docker pull docker.io/elasticsearch:6.5.1 # 安装 docker run -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -d -p 9200:9200 -p 9300:9300 --name myELK elkImageId

     

    ElasticSearch默认2个G堆内存, 为了防止虚拟机内存不够,要手动指定elk启动参数 -e ES_JAVA_OPTS="-Xms256m -Xmx256m" , 9200是elk暴露的RestFUL HTTP服务端口, 9300是java客户端调用的端口.

    在启动时遇到异常:   max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]  , 意为ElasticSearch用户虚拟机能使用的虚拟内存区域太小,需要调大到262144以上 , 按如下操作:

    # 修改配置文件
    vi /etc/sysctl.conf
    # 最后一行添加
    vm.max_map_count=655300
    # 重载该配置文件
    sysctl -p

     

     

    访问

    http://ip:9200/ 返回如下信息表示成功启动

    {
      "name" : "vcabSCo",
      "cluster_name" : "docker-cluster",
      "cluster_uuid" : "LPiwCqIYQACz5Eir5P1qBQ",
      "version" : {
        "number" : "6.5.1",
        "build_flavor" : "default",
        "build_type" : "tar",
        "build_hash" : "8c58350",
        "build_date" : "2018-11-16T02:22:42.182257Z",
        "build_snapshot" : false,
        "lucene_version" : "7.5.0",
        "minimum_wire_compatibility_version" : "5.6.0",
        "minimum_index_compatibility_version" : "5.0.0"
      },
      "tagline" : "You Know, for Search"
    }

     

     http://ip:9200/index/type/id 为查询指定id

    http://ip:9200/index/type/_search 为查询所有

     

    ElasticSearch 各组件概念

    索引 = mysql数据库

    类型 = mysql数据表

    文档 = mysql表字段内容 ( ES中使用json数据保存 )

    processon地址: https://www.processon.com/diagraming/5ceb8caee4b0899ed43db40e

    ElasticSearch和Mysql对应关系

    技术 库名  
    mysql Databases Tables Rows Columns  
    ElasticSearch Indices Types Documents Fields  

     

     

    java连接ELK有两种方式

    方式一: jest

    jest是用于直联ElasticSearch服务的, 就好像redisClient 直联redis服务一样.

    默认jest是不生效的, 需要导入jest的工具包(io.searchbox.client.JestClient) , 注意jest的大版本号和ES的大版本号要一致.

    该模式的自动配置类为: JestAutoConfiguration

    pom.xml导依赖 

    导入之后JestAutoConfiguration里的内容就不会报红色错误了, 但是我发现高版本springboot好像不导也正常.

            <!--取消spring-boot-starter-data-elasticsearch依赖-->
            <!--<dependency>-->
                <!--<groupId>org.springframework.boot</groupId>-->
                <!--<artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
            <!--</dependency>-->
    
    
            <dependency>
                <groupId>io.searchbox</groupId>
                <artifactId>jest</artifactId>
                <version>5.3.3</version>
            </dependency>

     

    遇到错误,Jest无法存数据到ElasticSearch中, java后台不报错, ElasticSearch也不报错, 也没有日志显示错误 ,

    目前jest5.3.3对ElasticSearch5.6.12 可以正常交互 ,   但jest5.3.3对ES6 或jest6对ES6无法正常交互. 晕死人.

     

    方式二: SpringData ElasticSearch

    通过使用Spring工具类转发,步骤如下

    1. pom.xml导入spring-boot-starter-data-elasticsearch依赖

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

     

    2. 需要在application.properties中配置clusterNodes;clusterName

    #使用springData连接ES
    #集群名,访问 http://centos:9200/ 后返回的cluster_name即是节点名
    spring.data.elasticsearch.cluster-name=elasticsearch
    #IP:9300, 用的是9300通信
    spring.data.elasticsearch.cluster-nodes=centos:9300

     3. 编写ElasticsearchRepository子接口来操作ES (就好像hibernateTemplate一样, 和JPA用法一致)

     

    4. ElasticSearchTemplate 操作ES , 就好像(jdbcTemplate, 一样, 未实验, 只做了Repository的实验)

     

     

    另外特别注意在使用SpringData elasticSearch 和 elasticSearch对接时的要注意版本问题 , 如何找版本匹配参考下图流程 , 懒人直接打开 https://github.com/spring-projects/spring-data-elasticsearch

     遇上版本不匹配的概率较高, 会发生异常"NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{3mA3x7OSSjustRG1_ZytWg}{centos}{192.168.2.106:9300}]"   一般有两种处理方式 

    1. 调整springboot的版本(不建议)

    2. 调整ElasticSearch的版本(建议)

    3. Elasticsearch报 NoNodeAvailableException 的解决办法==>https://blog.csdn.net/adsl624153/article/details/78935796   (未亲测)

     

    参考

    SpringBoot整合ElasticSearch实现多版本的兼容==>https://www.cnblogs.com/xuwujing/p/8998168.html

    elasticsearch安装之各种坑==>https://www.cnblogs.com/gudulijia/p/6761231.html

     

    我的项目git地址

    https://gitee.com/KingBoBo/springboot-04-elastic-search

    转载于:https://www.cnblogs.com/whatlonelytear/p/10894013.html

    展开全文
  • springboot 整合 elasticsearch 非常简单第一步:引入maven依赖&lt;dependency&gt; &lt;groupId&gt;org.elasticsearch.client&lt;/groupId&gt; &lt;artifactId&gt;transport&...
  • SpringBoot Elasticsearch工具类封装

    千次阅读 2019-06-19 11:59:28
    最近项目需要封装Elasticsearch工具类,特此记录便于日后查阅。 1、maven依赖 <dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</...
  • 工作之余想开发一个前后端分离... bboss是一套基于query dsl语法操作和访问分布式搜索引擎elasticsearch的o/r mapping高性能开发库,底层基于es restful api。基于bboss elasticsearch,可以快速编写出访问和操作ela...
  • 2.springboot使用elasticsearch 1.springboot有两种方式与elasticsearch交互 通过jest的方式,默认是不启动的 1).首先创建springboot的项目,选中web以及nosql的elasticsearch 2).因为使用的是是jest的方式,需要把...
  • 代码地址:https://github.com/zhaoyunxing92/spring-boot-learn-box/tree/master/spring-boot-elasticsearch/spring-boot-data-elasticsearch 这个就跟我在以前写的【springboot mongodb配置解析】一样效果,单纯...
  • SpringBoot Elasticsearch组合查询封装

    千次阅读 2019-06-19 12:53:50
    SpringBoot Elasticsearch工具类封装 本文包括ES四大查询模式构建工具类,一个查询模式定义类,一个构建工厂类,一个最终拼装类。使用了简单工厂设计模式加反射,特此记录便于日后查阅。 1、代码结构 2、maven...
  • SpringBoot整合Elasticsearch

    万次阅读 多人点赞 2018-11-09 18:33:42
    1 SpringBoot整合Spring Data Elasticsearch Elasticsearch提供的Java客户端有一些不太方便的地方: 很多地方需要拼接Json字符串,在java中拼接字符串有多恐怖你应该懂的 需要自己把对象序列化为json存储 查询...
  • 本文主要研究一下springboot elasticsearch autoconfigure ElasticsearchAutoConfiguration spring-boot-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/autoconfigure/data/elasticsearch/...
  • 本文主要研究一下springboot elasticsearch healthIndicator ElasticsearchHealthIndicatorProperties spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/...
  • elasticsearch基础  这里假设各位已经简单了解过elasticsearch,并不对es进入更多的,更深层次的解释,如有必要,会在写文章专门进行es讲解。  Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。...
  • 在pom文件中添加Elasticsearch Maven依赖 &lt;dependency&gt; &lt;groupId&gt;org.elasticsearch.client&lt;/groupId&gt; &lt;artifactId&gt;elasticsearch-rest-hig...
  • elasticsearch 是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。 Git地址 https://gitee.com/wqrzsy/lp-demo/tree/master/lp-elasticsearch-demo 更多demo请...
  • import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.client.Client; import org.elasticsearch.comm...
  • springboot集成elasticsearch注意事项

    万次阅读 多人点赞 2019-07-31 19:27:29
    一、elasticsearch基础  这里假设各位已经简单了解过elasticsearch,并不对es进入更多的,更深层次的解释,如有必要,会在写文章专门进行es讲解。  Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。...

空空如也

1 2 3 4 5 ... 20
收藏数 6,824
精华内容 2,729
关键字:

bboss