准备
- 添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <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> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.6</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
-
修改配置文件
# 9200端口是用来让HTTP REST API来访问ElasticSearch,而9300端口是传输层监听的默认端口 elasticsearch.ip=h120 elasticsearch.port=9300 elasticsearch.pool=5 #注意cluster.name需要与config/elasticsearch.yml中的cluster.name一致 elasticsearch.cluster.name=my-application
-
编写配置类ESConfig
import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.net.InetAddress; @Configuration public class ESConfig { private static final Logger LOGGER = LoggerFactory.getLogger(ESConfig.class); @Value("${elasticsearch.ip}") private String hostName; @Value("${elasticsearch.port}") private String port; @Value("${elasticsearch.cluster.name}") private String clusterName; @Value("${elasticsearch.pool}") private String poolSize; @Bean(name = "transportClient") public TransportClient transportClient() { LOGGER.info("Elasticsearch初始化开始。。。。。"); TransportClient transportClient = null; try { // 配置信息 Settings esSetting = Settings.builder() .put("cluster.name", clusterName) //集群名字 .put("client.transport.sniff", true)//增加嗅探机制,找到ES集群 .put("thread_pool.search.size", Integer.parseInt(poolSize))//增加线程池个数,暂时设为5 .build(); //配置信息Settings自定义 transportClient = new PreBuiltTransportClient(esSetting); TransportAddress transportAddress = new TransportAddress(InetAddress.getByName(hostName), Integer.valueOf(port)); transportClient.addTransportAddresses(transportAddress); } catch (Exception e) { LOGGER.error("elasticsearch TransportClient create error!!", e); } return transportClient; } }
文档的增删查改
TransportClient支持链式操作,用起来比spring-data-elasticsearch爽。
- 变量定义
private String indexName = "goods"; private String ikIndexName = "ik"; private String typeName = "goods"; @Autowired GoodsMapper goodsMapper; @Autowired TransportClient client;
goodsMapper用于查询商品信息
-
创建索引
/** 创建索引*/ @Test public void createIndex(){ IndicesAdminClient indices = client.admin().indices(); CreateIndexResponse response= indices.prepareCreate(indexName).execute().get(); System.out.println(response.isAcknowledged()); }
IndicesAdminClient封装了对索引层面的操作,
-
删除索引
/** 删除索引*/ @Test public void deleteIndex(){ DeleteIndexResponse deleteIndexResponse = client.admin().indices().prepareDelete(indexName).get(); System.out.println(deleteIndexResponse.isAcknowledged()); }
-
索引单条数据
/** 索引数据*/ @Test public void saveData(){ JSONObject data = new JSONObject(); data.put("name", "jack"); data.put("type", "1"); XContentType contentType = XContentType.JSON; // 不指定id es分配id IndexResponse indexResponse = client.prepareIndex(indexName, typeName). setSource(data, contentType).get(); System.out.println(indexResponse.status().name()); // 指定id indexResponse = client.prepareIndex(indexName, typeName, "2"). setSource(data, contentType).get(); System.out.println(indexResponse.status().name()); }
-
索引多条数据
/** bulk操作,批量索引数据*/ @Test public void bulkSave() throws Exception { List<Goods> cars = goodsMapper.selectAll(); BulkRequestBuilder bulkRequestBuilder = client.prepareBulk(); for (Goods car : cars) { Map map = Obj2Map(car); bulkRequestBuilder.add(client.prepareIndex(indexName, typeName, car.getId() + "").setSource(map)); } BulkResponse bulkItemResponses = bulkRequestBuilder.get(); System.out.println(bulkItemResponses.hasFailures()); } public Map<String,Object> Obj2Map(Object obj) throws Exception{ Map<String,Object> map=new HashMap<String, Object>(); Field[] fields = obj.getClass().getDeclaredFields(); for(Field field:fields){ field.setAccessible(true); map.put(field.getName(), field.get(obj)); } return map; }
将查出的goods数据存入es索引库中。obj2Map会将所有字段存入map,需要只存储部分字段时,可以用注解在obj2map中只转换需要的字段。
-
删除数据
/** 删除索引数据*/ @Test public void delete(){ DeleteResponse deleteResponse = client.prepareDelete(indexName, typeName, "2").get(); System.out.println(deleteResponse.getResult().name()); }
-
获取指定id数据
setStoredFields("_source")只返回get回的"_source"字段,像es中get数据时会返回类似于@Test public void get(){ /** 返回指定字段*/ String[] sourceFields = {"id","name","aPrice"}; GetResponse documentFields = client.prepareGet(indexName, typeName, 22 + "").setStoredFields("_source").setFetchSource(sourceFields, null).get(); Map<String, Object> source = documentFields.getSource(); for (Map.Entry entry : source.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); } }
{"_index": "goods", "_type": "goods", "_id": "22", "_version": 1, "found": true, "_source": { "aPrice": 5.3, "id": 22, "img2": null, "img1": null } }
的数据,这里就只拿回_source,即这个id的存储的数据,,,
setFetchSource(sourceFields, null),只返回_source中的id、name、aprice。
- 修改数据
/** 修改数据*/ @Test public void update() throws Exception { Goods goods = goodsMapper.selectByPrimaryKey(24); goods.setaPrice(1000D); client.prepareUpdate(indexName,typeName,"24").setDoc(JSONObject.toJSONString(goods), XContentType.JSON).get(); // Map<String, Object> stringObjectMap = Obj2Map(goods); // client.prepareUpdate(indexName,typeName,"121").setDoc(stringObjectMap).get(); }
搜索文档
- 通用的 client.prepareSearch()提供搜索功能, ,setFrom() 、setSize()用于分页,,setIndices()、setTypes指定搜索的index、type,,setSearchType()设定查询类型,可选值为QUERY_THEN_SEARCH、DFS_QUERY_THEN_SEARCH,,setFetchSource()指定查询出的结果要哪些字段,,setQueryBuilder()制定不同QueryBuilder,es提供多种queryBulder。
- execSearch 执行搜索
private void execSearch(SearchRequestBuilder builder){ SearchResponse response = builder.get(); Iterator<SearchHit> iterator = response.getHits().iterator(); while (iterator.hasNext()){ SearchHit next = iterator.next(); System.out.println( next.getSourceAsMap()); } }
-
/** 有点类似multiMatch*/ @Test public void queryStringQueryBuilder(){ SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(new QueryStringQueryBuilder("帕杰罗·劲畅").field("description")).setSize(10); // SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(new QueryStringQueryBuilder("ZJYLQ").field("pycode")).setSize(10); // SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(new QueryStringQueryBuilder("XZJYLQQ").field("pycode")).setSize(10); execSearch(builder); } private void execSearch(SearchRequestBuilder builder){ SearchResponse response = builder.get(); Iterator<SearchHit> iterator = response.getHits().iterator(); while (iterator.hasNext()){ SearchHit next = iterator.next(); System.out.println( next.getSourceAsMap()); } } /** 单字段匹配*/ @Test public void matchQueryBuilder(){ // QueryBuilder // MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("jfcode", "30049"); /** 单字段查询*/ MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("pycode", "XZJYLQQ"); // MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("pycode", "JYLQQ"); SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(matchQueryBuilder); execSearch(builder); } /** 多字段匹配*/ @Test public void multiMatchQueryBuilder(){ /** 多字段对value查询*/ MultiMatchQueryBuilder multiMatchQueryBuilder = new MultiMatchQueryBuilder("滤清器", "name","typeName"); SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(multiMatchQueryBuilder).setSize(10); execSearch(builder); } /** 范围查询, gt lt gte lte分别代表 > < >= <=*/ @Test public void rangeQueryBuilder(){ // 12<=bPrice<=13 RangeQueryBuilder queryBuilder = new RangeQueryBuilder("bPrice"); queryBuilder.gte(12); queryBuilder.lte(13); SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10); execSearch(builder); } /** 根据id查询*/ @Test public void idsQuery(){ IdsQueryBuilder queryBuilder = new IdsQueryBuilder().types(typeName).addIds("10","21","22"); SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10); execSearch(builder); } /** 符合查询,, must必须满足、mustnot必须不满足、should可满足可不满足*/ @Test public void boolMatchQuery(){ /** 多字段对value查询*/ BoolQueryBuilder queryBuilder = new BoolQueryBuilder(); queryBuilder.must(new MatchQueryBuilder("marketPrice", "8")); queryBuilder.mustNot(new RangeQueryBuilder("bPrice").gte(12).lt(13)); queryBuilder.should(new MatchQueryBuilder("marketPrice", "8")); /** marketPrice=8 并且 bPrice不在12、13之间*/ SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10); execSearch(builder); } // ? * 分别代替一个字符、多个字符。 @Test public void wildCardMatchQuery(){ /** 多字段对value查询*/ WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("jfcode", "*36033"); // WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("jfcode", "?36033"); // WildcardQueryBuilder queryBuilder = new WildcardQueryBuilder("name", "*机油滤*"); /** marketPrice=8 并且 bPrice不在12、13之间*/ SearchRequestBuilder builder = client.prepareSearch(indexName).setQuery(queryBuilder).setSize(10); execSearch(builder); }