Java elasticSearch-api的具体操作步骤讲解
作者:丶落幕
这篇文章主要介绍了elasticSearch-api的具体操作步骤讲解,本文通过详细的步骤介绍和图文代码展示讲解了该项技术,需要的朋友可以参考下
使用步骤
1.环境准备
用的是windows版,自行下载
链接: 下载地址
2.针对索引操作
这里是kibana上操作的(也可以用postman操作):
#创建索引,指定文档id PUT /test1/type1/1 { "name":"张三", "age":30 } #创建索引规则(类似数据库建表) PUT /test2 { "mappings": { "properties": { "name":{ "type":"text" }, "age":{ "type": "integer" }, "birthday":{ "type": "date" } } } } #获取索引的信息,properties类型 GET test2 #创建索引,properties不指定类型会有默认类型 #也可以用作修改,但是必须写上全部字段,不然会丢失未写字段 PUT /test3/_doc/1 { "name":"张三", "age":30, "birth":"1991-06-23" } GET test3 #查看es健康状态 GET _cat/health #查看所有索引状态 GET _cat/indices?v #修改 POST /test3/_doc/1/_update { "doc":{ "name":"李四" } }
3.针对doc操作(增删改)
代码如下(示例):
#新增索引,并添加doc POST /chen/user/1 { "name":"张三", "age":11, "desc":"一顿操作猛如虎,一看工资2500", "tags":["技术宅","温暖","直男"] } POST /chen/user/2 { "name":"李四", "age":12, "desc":"憨批", "tags":["渣男","旅游","交友"] } POST /chen/user/3 { "name":"王五", "age":13, "desc":"瓜怂", "tags":["靓女","旅游","美食"] } POST /chen/user/4 { "name":"刘六", "age":14, "desc":"锅盔", "tags":["衰仔","旅游","美食"] } #获取数据 GET chen/user/1 #更新数据 POST chen/user/1/_update { "doc":{ "name":"更新" } } #删除 DELETE chen/user/1 #条件查询,匹配度越高,_score(分值)越高 GET chen/user/_search?q=name:李 GET chen/user/_search?q=name:李四 #等价于上面 GET chen/user/_search { "query": { "match": { "name": "李四" } } }
4.针对doc操作(查)
查询1(示例):
#_source结果过滤(指定需要字段结果集) #sort排序 #from-size分页(类似limit ) #注意:这个查询是不可以些多个字段的(我试过了) GET chen/user/_search { "query": { "match": { "name": "李四" } }, "_source": ["name","age"], "sort": [ { "age": { "order": "asc" } } ], "from":0, "size":1 } #多条件精确查询 #以下都是bool的二级属性 #must:必须 #should,满足任意条件 #must_not,表示不满足 GET chen/user/_search { "query": { "bool": { "must": [ {"match": { "name": "李四" }}, {"match": { "age": 11 }} ] } } } #过滤.注意filter是bool(多条件)的二级属性 GET chen/user/_search { "query": { "bool": { "must": [ {"match": { "name": "李四" }} ], "filter": { "range": { "age": { "gte": 10, "lte": 20 } } } } } } #分词器依然有效 #多个条件空格隔开就行,只要满足其中一个,就会被逮到 GET chen/user/_search { "query": { "match": { "tags": "男 技术" } } } #精确查询,结果只能为1,多条直接不显示 GET chen/user/_search { "query": { "term": { "name": "李四" } } }
查询2(示例):
#新建索引 PUT test4 { "mappings": { "properties": { "name":{ "type": "text" }, "desc":{ "type": "keyword" } } } } #插入数据 PUT test4/_doc/1 { "name":"张三name", "desc":"张三desc" } PUT test4/_doc/2 { "name":"张三name2", "desc":"张三desc2" } #分词器查询(并不是查询索引里的数据,而是将text的内容用分词器拆分的结果) GET _analyze { "analyzer": "keyword", "text": ["张三name"] } GET _analyze { "analyzer": "standard", "text": "张三name" } GET test4/_search { "query": { "term": { "name": "张" } } } #==keyword不会被分词器解析== GET test4/_search { "query": { "term": { "desc": "张三desc" } } }
查询3(示例):
PUT test4/_doc/3 { "t1":"22", "t2":"2020-4-6" } PUT test4/_doc/4 { "t1":"33", "t2":"2020-4-7" } #精确查询多个值 GET test4/_search { "query": { "bool": { "should": [ { "term": { "t1": "22" } }, { "term": { "t1": "33" } } ] } } } #highlight:高亮 #pre_tags,post_tags:自定义高亮条件,前缀后缀 GET chen/user/_search { "query": { "match": { "name": "李四" } }, "highlight": { "pre_tags": "<p class='key' style='color:red'", "post_tags": "</p>", "fields": { "name":{} } } }
5.java-api
索引操作:
public class ES_Index { private static final String HOST_NAME = "localhost"; private static final Integer PORT = 9200; private static RestHighLevelClient client; //创建ES客户端 static { RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(HOST_NAME, PORT)); client = new RestHighLevelClient(restClientBuilder); } //关闭ES客户端 public void close() { if (null != client) { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } //创建索引 public void addIndex() throws IOException { //创建索引 CreateIndexRequest request = new CreateIndexRequest("chen"); CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT); //响应状态 System.out.println("索引创建操作: " + response.isAcknowledged()); } //查询索引 public void selectIndex() throws IOException { GetIndexRequest request = new GetIndexRequest("chen"); GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT); System.out.println("索引查询操作: " +response.getAliases()); System.out.println("索引查询操作: " +response.getMappings()); System.out.println("索引查询操作: " +response.getSettings()); } //删除索引 public void deleteIndex() throws IOException { DeleteIndexRequest request = new DeleteIndexRequest("chen"); AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT); System.out.println("索引删除操作: "+response.isAcknowledged()); } public static void main(String[] args) throws IOException { ES_Index index=new ES_Index(); //index.addIndex(); //index.selectIndex(); index.deleteIndex(); index.close(); } }
文档操作:
public class ES_Doc { private static final String HOST_NAME = "localhost"; private static final Integer PORT = 9200; private static RestHighLevelClient client; //创建ES客户端 static { RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(HOST_NAME, PORT)); client = new RestHighLevelClient(restClientBuilder); } //关闭ES客户端 public void close() { if (null != client) { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } //插入数据 public void addDoc() throws IOException { IndexRequest request = new IndexRequest(); User user = new User("张三", "男", 18); //向es插入数据,必须将数据转换为json格式 String userJson = new ObjectMapper().writeValueAsString(user); request.index("user").id("1001").source(userJson, XContentType.JSON); IndexResponse response = client.index(request, RequestOptions.DEFAULT); System.out.println("文档创建操作: " + response.getResult()); } //修改数据(局部修改) public void updateDoc() throws IOException { UpdateRequest request = new UpdateRequest(); request.index("user").id("1001").doc(XContentType.JSON, "sex", "女"); UpdateResponse response = client.update(request, RequestOptions.DEFAULT); System.out.println("文档修改操作: " + response.getResult()); } //获取数据 public void getDoc() throws IOException { GetRequest request = new GetRequest(); request.index("user").id("1001"); GetResponse response = client.get(request, RequestOptions.DEFAULT); User user = new ObjectMapper().readValue(response.getSourceAsString(), User.class); System.out.println("文档获取操作: " + user); } //删除数据 public void deleteDoc() throws IOException { DeleteRequest request = new DeleteRequest(); request.index("user").id("1001"); DeleteResponse response = client.delete(request, RequestOptions.DEFAULT); System.out.println("文档删除操作: " + response.getResult()); } //批量插入数据 public void addBatch() throws IOException { BulkRequest request = new BulkRequest(); request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "张三", "sex", "男", "age", 10)); request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "李四", "sex", "男", "age", 20)); request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "王五", "sex", "女", "age", 30)); request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "赵六", "sex", "男", "age", 40)); request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "孙七", "sex", "女", "age", 50)); BulkResponse response = client.bulk(request, RequestOptions.DEFAULT); System.out.println("文档批量新增操作: " + response.getTook()); System.out.println("文档批量新增操作: " + !response.hasFailures());//是否失败 } //批量删除数据 public void deleteBatch() throws IOException { BulkRequest request = new BulkRequest(); request.add(new DeleteRequest().index("user").id("1001")); request.add(new DeleteRequest().index("user").id("1002")); request.add(new DeleteRequest().index("user").id("1003")); request.add(new DeleteRequest().index("user").id("1004")); request.add(new DeleteRequest().index("user").id("1005")); BulkResponse response = client.bulk(request, RequestOptions.DEFAULT); System.out.println("文档批量删除操作: " + response.getTook()); System.out.println("文档批量删除操作: " + !response.hasFailures());//是否失败 } //查询(重点) public void searchDoc() throws IOException { SearchRequest request = new SearchRequest(); request.indices("user"); //1.查询索引中的全部数据 //request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); //2.查询年龄为30的数据 //request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 30))); //3.分页查询,当前第0页,每页两条 //request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).from(0).size(2)); //4.排序,倒序 //request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort("age", SortOrder.DESC)); //5.过滤字段(排除和包含,也可以是数组) //request.source(new SearchSourceBuilder().fetchSource("name", null)); //6.组合查询 //BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); //6.1 must相当于and //boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30)); //boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "女")); //6.2 should相当于or //boolQueryBuilder.should(QueryBuilders.matchQuery("age", 30)); //boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "女")); //request.source(new SearchSourceBuilder().query(boolQueryBuilder)); //7.范围查询 //request.source(new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").gte(30).lte(40))); //8.模糊查询Fuzziness.ONE即只差1个字符 //request.source(new SearchSourceBuilder().query(QueryBuilders.fuzzyQuery("name", "王五").fuzziness(Fuzziness.ONE))); //9.高亮显示 //SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchPhraseQuery("name", "张三")); //builder.highlighter(new HighlightBuilder().preTags("<font color='red'>").postTags("</font>").field("name")); //request.source(builder); //10.聚合查询 //SearchSourceBuilder builder = new SearchSourceBuilder(); //MaxAggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age"); //builder.aggregation(aggregationBuilder); //request.source(builder); //11.分组查询 SearchSourceBuilder builder = new SearchSourceBuilder(); TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age"); builder.aggregation(aggregationBuilder); request.source(builder); SearchResponse response = client.search(request, RequestOptions.DEFAULT); SearchHits hits = response.getHits(); System.out.println("--条数: " + hits.getTotalHits()); System.out.println("--用时: " + response.getTook()); hits.forEach((item)->{ System.out.println("--数据: " + item.getSourceAsString()); }); } public static void main(String[] args) throws IOException { ES_Doc doc = new ES_Doc(); //doc.addDoc(); //doc.updateDoc(); //doc.getDoc(); //doc.deleteDoc(); //doc.addBatch(); //doc.deleteBatch(); doc.searchDoc(); doc.close(); } }
6.spring-data-elasticsearch
实体类: 关键在于@Document和@Field注解
shards 代表分片
replicas 代表副本
@Data @NoArgsConstructor @AllArgsConstructor @Document(indexName = "product", shards = 3, replicas = 1) public class Product { @Id private Long id;//商品唯一标识 @Field(type = FieldType.Text) private String title;//商品名称 @Field(type = FieldType.Keyword) private String category;//分类名称 @Field(type = FieldType.Double) private Double price;//商品价格 @Field(type = FieldType.Keyword,index = false) private String images;//图片地址 }
dao层: 这样就已经可以了,类似mybatis-plus的BaseMapper,封装好了一些操作
@Repository public interface ProductDao extends ElasticsearchRepository<Product,Long> { }
yaml :不用怎么配置,默认就去找localhost:9200
测试 :不知道为啥dao的很多方法都过时了,看源码注释让回去用elasticsearchRestTemplate,感觉更繁琐
@SpringBootTest class ElasticsearchApplicationTests { @Autowired ElasticsearchRestTemplate elasticsearchRestTemplate; @Autowired ProductDao productDao; @Test void createIndex() { //创建索引,系统初始化会自动创建索引 System.out.println("创建索引"); } @Test void deleteIndex() { //创建索引,系统初始化会自动创建索引 boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class); System.out.println("删除索引 = " + flg); } //新增数据 @Test void addDoc() { Product product = new Product(); product.setId(1001L); product.setTitle("华为手机"); product.setCategory("手机"); product.setPrice(2999.0); product.setImages("www.huawei.com"); productDao.save(product); } //修改 @Test void updateDoc() { Product product = new Product(); product.setId(1001L); product.setTitle("小米手机"); product.setCategory("手机"); product.setPrice(4999.0); product.setImages("www.xiaomi.com"); productDao.save(product); } //根据 id 查询 @Test void findById() { Product product = productDao.findById(1001L).get(); System.out.println(product); } //查询所有 @Test void findAll() { Iterable<Product> products = productDao.findAll(); for (Product product : products) { System.out.println(product); } } //删除 @Test public void delete() { productDao.deleteById(1001L); } //批量新增 @Test public void saveAll() { List<Product> productList = new ArrayList<>(); for (int i = 0; i < 10; i++) { Product product = new Product(); product.setId((long) i); product.setTitle("[" + i + "]小米手机"); product.setCategory("手机"); product.setPrice(1999.0 + i); product.setImages("http://www.atguigu/xm.jpg"); productList.add(product); } productDao.saveAll(productList); } //分页查询 @Test void findByPageable() { Sort orders = Sort.by(Sort.Direction.DESC, "id"); Pageable pageable = PageRequest.of(0, 5, orders); Page<Product> products = productDao.findAll(pageable); products.forEach(System.out::println); } /** * term 查询 * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象 */ @Test void termQuery() { TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机"); Iterable<Product> products = productDao.search(termQueryBuilder); products.forEach(System.out::println); } /** * term 查询加分页 */ @Test void termQueryByPage() { PageRequest pageRequest = PageRequest.of(0, 5); TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机"); Iterable<Product> products = productDao.search(termQueryBuilder, pageRequest); products.forEach(System.out::println); } }
到此这篇关于elasticSearch-api的具体操作步骤讲解的文章就介绍到这了,更多相关elasticSearch-api详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!