0
点赞
收藏
分享

微信扫一扫

ElasticSearch增删改查

ElasticSearch增删改查


1 HTTP方式

1.1 幂等

POST 不是幂等的。

GET,PUT,DELETE,HEAD,OPTIONS和TRACE是幂等。

http://restful.p2hp.com/learn/idempotent-rest-apis

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

https://stackoverflow.com/questions/7016785/is-put-delete-idempotent-with-rest-automatic

1.2 索引CRUD

# delete/404

DELETE index01

# search all indeces

GET _cat/indices

# get/404

GET index01

# 200/404

HEAD index01

# 第一次405 资源被禁止

POST index02

# 创建,第二次400页面不存在或者请求错误

PUT index01


GET /


1.3 文档CRUD

# 可以更新N次

POST index01/_update/1

{"doc":{}}

# 405 资源禁止

PUT index01/_update/1

{"doc":{}}

# 读取

GET index01/_doc/1

# 405 资源禁止

PUT index01/_doc

{}

# 第二次409 与服务器当前资源冲突

POST index01/_create/4

{}

# 第二次409 与服务器当前资源冲突

PUT index01/_create/3

{}

# 每次文档不一样

POST index01/_doc

{}

# 每次版本不一样

POST index01/_doc/1

{}

# 每次版本不一样

PUT index01/_doc/1

{}


2 JavaAPI方式

2.1 POM依赖

<dependency>

   <groupId>org.elasticsearch</groupId>

   <artifactId>elasticsearch</artifactId>

   <version>7.8.0</version>

</dependency>

<!-- elasticsearch的客户端 -->

<dependency>

   <groupId>org.elasticsearch.client</groupId>

   <artifactId>elasticsearch-rest-high-level-client</artifactId>

   <version>7.8.0</version>

</dependency>

<!-- elasticsearch依赖2.x的log4j -->

<dependency>

   <groupId>org.apache.logging.log4j</groupId>

   <artifactId>log4j-api</artifactId>

   <version>2.8.2</version>

</dependency>

<dependency>

   <groupId>org.apache.logging.log4j</groupId>

   <artifactId>log4j-core</artifactId>

   <version>2.8.2</version>

</dependency>

<dependency>

   <groupId>com.fasterxml.jackson.core</groupId>

   <artifactId>jackson-databind</artifactId>

   <version>2.9.9</version>

</dependency>

2.2 索引CRUD

2.2.1 创建索引

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 创建索引

CreateIndexRequest request = new CreateIndexRequest("user");

CreateIndexResponse createIndexResponse =

       esClient.indices().create(request, RequestOptions.DEFAULT);


// 响应状态

boolean acknowledged = createIndexResponse.isAcknowledged();

System.out.println("索引操作 :" + acknowledged);


esClient.close();

2.2.2 删除索引

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 查询索引

DeleteIndexRequest request = new DeleteIndexRequest("user");


AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT);


// 响应状态

System.out.println(response.isAcknowledged());


esClient.close();


2.2.3 查询索引

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 查询索引User

GetIndexRequest request = new GetIndexRequest("user");

// 查询所有索引

// GetIndexRequest request = new GetIndexRequest("*");


GetIndexResponse getIndexResponse =

       esClient.indices().get(request, RequestOptions.DEFAULT);


// 响应状态

System.out.println(getIndexResponse.getAliases());

System.out.println(getIndexResponse.getMappings());

System.out.println(getIndexResponse.getSettings());


esClient.close();


2.3 文档CRUD

2.3.1 实体User

public class User {

   private String name;

   private String sex;

   private Integer age;


   public String getName() {

       return name;

   }


   public void setName(String name) {

       this.name = name;

   }


   public String getSex() {

       return sex;

   }


   public void setSex(String sex) {

       this.sex = sex;

   }


   public Integer getAge() {

       return age;

   }


   public void setAge(Integer age) {

       this.age = age;

   }

}


2.3.2 插入单条文档

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 插入数据

IndexRequest request = new IndexRequest();

request.index("user").id("1001");


User user = new User();

user.setName("tom");

user.setAge(30);

user.setSex("男");


// 向ES插入数据,必须将数据转换位JSON格式

ObjectMapper mapper = new ObjectMapper();

String userJson = mapper.writeValueAsString(user);

request.source(userJson, XContentType.JSON);


IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);


System.out.println(response.getResult());


esClient.close();

2.3.3 批量插入文档

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);

for (int j = 0; j < 50; j++) {

   // 批量插入数据

   BulkRequest request = new BulkRequest();

   System.out.println(j);

   System.out.println(new Date());

   for (int i = 0; i < 100_000; i++) {

       request.add(new IndexRequest().index("user").source(XContentType.JSON, "name", "tom" + i, "age", i * 11, "sex", "男"));

   }

   System.out.println(new Date());

   BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);

   System.out.println(response.getTook());

   System.out.println(response.getItems());

}


esClient.close();


2.3.4 获取单条文档

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 查询数据

GetRequest request = new GetRequest();

request.index("user").id("1001");

GetResponse response = esClient.get(request, RequestOptions.DEFAULT);


System.out.println(response.getSourceAsString());


esClient.close();


2.3.5 更新单条数据

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 修改数据

UpdateRequest request = new UpdateRequest();

request.index("user").id("1001");

request.doc(XContentType.JSON, "sex", "女");


UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);


System.out.println(response.getResult());


esClient.close();


2.3.6 删除单条数据

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);



DeleteRequest request = new DeleteRequest();

request.index("user").id("1001");


DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);

System.out.println(response.toString());


esClient.close();


2.3.7 批量删除数据

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 批量删除数据

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"));


BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);

System.out.println(response.getTook());

System.out.println(response.getItems());


esClient.close();


2.3.8 查询所有

RestHighLevelClient esClient = new RestHighLevelClient(

       RestClient.builder(new HttpHost("localhost", 9200, "http"))

);


// 1. 查询索引的所有数据

SearchRequest request = new SearchRequest();

request.indices("user");


// 构造查询条件

SearchSourceBuilder builder = new SearchSourceBuilder();

builder.query(QueryBuilders.matchAllQuery());


request.source(builder);


SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);


SearchHits hits = response.getHits();


System.out.println(response.getTook());

System.out.println(hits.getTotalHits());

Iterator<SearchHit> iterator = hits.iterator();

while (iterator.hasNext()) {

   SearchHit hit = iterator.next();

   System.out.println(hit.getSourceAsString());

}


esClient.close();


2.3.9 组合查询

RestHighLevelClient esClient = new RestHighLevelClient(

               RestClient.builder(new HttpHost("localhost", 9200, "http"))

       );


       // 1. 查询索引中全部的数据

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));

//

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


       // 2. 条件查询 : termQuery

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 30)));

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


       // 3. 分页查询

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());

//        // (当前页码-1)*每页显示数据条数

//        builder.from(2);

//        builder.size(2);

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


//        // 4. 查询排序

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());

//        //

//        builder.sort("age", SortOrder.DESC);

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


//        // 5. 过滤字段

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());

//        //

//        String[] excludes = {"age"};

//        String[] includes = {};

//        builder.fetchSource(includes, excludes);

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


//        // 6. 组合查询

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder();

//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

//

//        //boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));

//        //boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "男"));

//        //boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex", "男"));

//        boolQueryBuilder.should(QueryBuilders.matchQuery("age", 30));

//        boolQueryBuilder.should(QueryBuilders.matchQuery("age", 40));

//

//        builder.query(boolQueryBuilder);

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


//        // 7. 范围查询

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder();

//        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");

//

//        rangeQuery.gte(30);

//        rangeQuery.lt(50);

//

//        builder.query(rangeQuery);

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


       // 8. 模糊查询

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder();

//        builder.query(QueryBuilders.fuzzyQuery("name", "wangwu").fuzziness(Fuzziness.TWO));

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


//        // 9. 高亮查询

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder();

//        TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("name", "zhangsan");

//

//        HighlightBuilder highlightBuilder = new HighlightBuilder();

//        highlightBuilder.preTags("<font color='red'>");

//        highlightBuilder.postTags("</font>");

//        highlightBuilder.field("name");

//

//        builder.highlighter(highlightBuilder);

//        builder.query(termsQueryBuilder);

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


//        // 10. 聚合查询

//        SearchRequest request = new SearchRequest();

//        request.indices("user");

//

//        SearchSourceBuilder builder = new SearchSourceBuilder();

//

//        AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");

//        builder.aggregation(aggregationBuilder);

//

//        request.source(builder);

//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);

//

//        SearchHits hits = response.getHits();

//

//        System.out.println(hits.getTotalHits());

//        System.out.println(response.getTook());

//

//        for ( SearchHit hit : hits ) {

//            System.out.println(hit.getSourceAsString());

//        }


       // 11. 分组查询

       SearchRequest request = new SearchRequest();

       request.indices("user");


       SearchSourceBuilder builder = new SearchSourceBuilder();


       AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");

       builder.aggregation(aggregationBuilder);


       request.source(builder);

       SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);


       SearchHits hits = response.getHits();


       System.out.println(hits.getTotalHits());

       System.out.println(response.getTook());


       for ( SearchHit hit : hits ) {

           System.out.println(hit.getSourceAsString());

       }




       esClient.close();



3 SpringData方式

3.1 POM依赖

<dependencies>

   <dependency>

       <groupId>org.projectlombok</groupId>

       <artifactId>lombok</artifactId>

   </dependency>


   <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-data-elasticsearch</artifactId>

   </dependency>


   <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-devtools</artifactId>

       <scope>runtime</scope>

       <optional>true</optional>

   </dependency>

   <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-test</artifactId>

       <scope>test</scope>

   </dependency>

   <dependency>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-test</artifactId>

   </dependency>

   <dependency>

       <groupId>junit</groupId>

       <artifactId>junit</artifactId>

   </dependency>

   <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-test</artifactId>

   </dependency>

</dependencies>


3.2 application.properties

# es服务地址

elasticsearch.host=127.0.0.1

# es服务端口

elasticsearch.port=9200


3.3 配置类

@ConfigurationProperties(prefix = "elasticsearch")

@Configuration

@Data

public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {

   private String host ;

   private Integer port ;


   //重写父类方法

   @Override

   public RestHighLevelClient elasticsearchClient() {

       RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));

       RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);

       return restHighLevelClient;

   }

}


3.4 实体类


@Data

@NoArgsConstructor

@AllArgsConstructor

@ToString

@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;//图片地址

}


3.5 实体类DAO

@Repository

public interface ProductDao extends ElasticsearchRepository<Product, Long> {


   List<Product> findByPriceBetween(double p1, double p2);

}



3.6 索引操作

@RunWith(SpringRunner.class)

@SpringBootTest

public class SpringDataESIndexTest {

   @Autowired

   private ElasticsearchRestTemplate elasticsearchRestTemplate;


   //创建索引并增加映射配置

   @Test

   public void createIndex(){


       boolean exists = elasticsearchRestTemplate.indexOps(Product.class).exists();

       System.out.println(exists);

       if (!exists) {

           boolean created = elasticsearchRestTemplate.indexOps(Product.class).create();

           System.out.println(created);

       }

       System.out.println("创建索引");

   }


   @Test

   public void deleteIndex(){

       boolean delete = elasticsearchRestTemplate.indexOps(Product.class).delete();

       System.out.println(delete);


   }


}


3.7 文档操作



@RunWith(SpringRunner.class)

@SpringBootTest

public class SpringDataESProductDaoTest {

   @Autowired

   private ProductDao productDao;


   /**

    * 新增

    */

   @Test

   public void save() {

       Product product = new Product();

       product.setId(1L);

       product.setTitle("华为手机");

       product.setCategory("手机");

       product.setPrice(2999.0);

       productDao.save(product);

   }


   //修改

   @Test

   public void update() {

       Product product = new Product();

       product.setId(1L);

       product.setTitle("小米2手机");

       product.setCategory("手机");

       product.setPrice(9999.0);

       productDao.save(product);

   }


   //根据id查询

   @Test

   public void findById() {

       Product product = productDao.findById(1L).get();

       System.out.println(product);

   }


   //查询所有

   @Test

   public void findAll() {

       Iterable<Product> products = productDao.findAll();

       for (Product product : products) {

           System.out.println(product);

       }

   }


   //删除

   @Test

   public void delete() {

       Product product = new Product();

       product.setId(1L);

       productDao.delete(product);

   }


   //批量新增

   @Test

   public void saveAll() {

       List<Product> productList = new ArrayList<>();

       for (int i = 0; i < 10; i++) {

           productList.add(new Product((long) i, "电视" + i, "电视", 100.0 * i, ""));

           productList.add(new Product(i * 20L, "手机" + i, "手机", 200.0 * i, ""));

       }

       productDao.saveAll(productList);

   }


   //分页查询

   @Test

   public void findByPageable() {

       //设置排序(排序方式,正序还是倒序,排序的id)

       Sort sort = Sort.by(Sort.Direction.DESC, "id");

       int currentPage = 0;//当前页,第一页从0开始,1表示第二页

       int pageSize = 5;//每页显示多少条

       //设置查询分页

       PageRequest pageRequest = PageRequest.of(currentPage, pageSize, sort);

       //分页查询

       Page<Product> productPage = productDao.findAll(pageRequest);

       for (Product Product : productPage.getContent()) {

           System.out.println(Product);

       }

   }



}


3.8 查询操作


@RunWith(SpringRunner.class)

@SpringBootTest

public class SpringDataESSearchTest {

   @Autowired

   private ProductDao productDao;

   @Autowired

   private ElasticsearchRestTemplate elasticsearchRestTemplate;


   /**

    * term查询

    * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象

    */

   @Test

   public void termQuery() {


       // QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("手机");

       // Query searchQuery = new NativeSearchQuery(queryStringQueryBuilder);


       TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");

       Query searchQuery = new NativeSearchQuery(termQueryBuilder);


       SearchHits<Product> search = elasticsearchRestTemplate.search(searchQuery, Product.class);

       for (SearchHit<Product> searchHit : search) {

           System.out.println(searchHit);

       }


   }


   /**

    * term查询加分页

    */

   @Test

   public void termQueryByPage() {

       int currentPage = 0;

       int pageSize = 5;

       //设置查询分页

       PageRequest pageRequest = PageRequest.of(currentPage, pageSize);

       TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");

       NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(termQueryBuilder);

       nativeSearchQuery.setPageable(pageRequest);


       // 排序

       nativeSearchQuery.addSort(Sort.by(Sort.Direction.DESC, "price"));


       SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);

       for (SearchHit<Product> productSearchHit : search) {

           System.out.println(productSearchHit);

       }


   }


   /**

    * 自定义查询

    */

   @Test

   public void findByPriceBetween() {

       List<Product> byPriceBetween = productDao.findByPriceBetween(1999, 2005);

       for (Product product : byPriceBetween) {

           System.out.println(product);

       }

   }


   @Test

   public void testAgg() {

       NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

       // 不查询任何结果

       queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));

       // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand

       queryBuilder.addAggregation(

               AggregationBuilders.terms("cats").field("category"));


       SearchHits<Product> search = elasticsearchRestTemplate.search(queryBuilder.build(), Product.class);


       Aggregations aggregations = search.getAggregations();


       Aggregation cats = aggregations.get("cats");

       ParsedStringTerms agg = (ParsedStringTerms)cats;

       // 获取桶

       List<? extends Terms.Bucket> buckets = agg.getBuckets();

       // 遍历

       for (Terms.Bucket bucket : buckets) {

           // 获取桶中的key

           System.out.println(bucket.getKeyAsString());

           // 获取桶中的文档数量

           System.out.println(bucket.getDocCount());

       }


   }


}


4 参考文献

https://www.bilibili.com/video/BV1hh411D7sb


举报

相关推荐

0 条评论