SpringBoot整合Elasticsearch并实现CRUD操作

配置准备

在build.gradle文件中添加如下依赖:

    compile "org.elasticsearch.client:transport:5.5.2"
    compile "org.elasticsearch:elasticsearch:5.5.2"
    //es 5.x的内部使用的 apache log4日志
    compile "org.apache.logging.log4j:log4j-core:2.7"
    compile "org.apache.logging.log4j:log4j-api:2.7"

这里spring boot使用的是1.5.4版,前些天spring boot 2正式版已经发布,spring boot 2新特性中有一条是支持kotlin,spring boot 2基于spring 5,spring 5也支持了koltin,所以spring也开始支持函数式编程。

关于版本兼容
SpringBoot整合Elasticsearch并实现CRUD操作_第1张图片

配置访问Elasticsearch的客户端,这里都使用原生es JavaAPI。

@Configuration
public class ElasticSearchConfig {

    @Bean(name = "client")
    public TransportClient getClient() {

        InetSocketTransportAddress node = null;
        try {
            node = new InetSocketTransportAddress(InetAddress.getByName("192.168.124.128"), 9300);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        Settings settings = Settings.builder().put("cluster.name", "my-es").build();
        TransportClient client = new PreBuiltTransportClient(settings);
        client.addTransportAddress(node);

        return client;
    }
}

SocketTransport端口可以使用http://ip:9200/_nodes方式查看,这里默认使用的是9300端口。

CRUD操作

新建一个控制器ElasticSearchController,使用原生的es JavaAPI。

@RestController
public class ElasticSearchController {

    @Autowired
    TransportClient client;
}

在控制器中添加增删查改方法

  • 增加操作
@PostMapping("add/book/novel")
    public ResponseEntity add(
            @RequestParam(name = "title") String title, @RequestParam(name = "authro") String author,
            @RequestParam(name = "word_count") int wordCount, 
            @RequestParam(name = "publish_date") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date publishDate
            )
    {
        try {
            XContentBuilder content = XContentFactory.jsonBuilder().startObject()
                    .field("title", title)
                    .field("author", author)
                    .field("word_count", wordCount)
                    .field("publish_date", publishDate.getTime())
                    .endObject();

            IndexResponse result = this.client.prepareIndex("book", "novel").setSource(content).get();
            return new ResponseEntity(result.getId(), HttpStatus.OK);

        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }
  • 删除操作
@DeleteMapping("/delete/book/novel")
    public ResponseEntity delete(@RequestParam(name = "id") String id)
    {
        DeleteResponse result = client.prepareDelete("book", "novel", id).get();
        return new ResponseEntity(result.getResult().toString(), HttpStatus.OK);
    }
  • 查找操作
@GetMapping("/get/book/novel")
    public ResponseEntity get(@RequestParam(name = "id", defaultValue="") String id)
    {
        if (id.isEmpty())
        {
            return new ResponseEntity(HttpStatus.NOT_FOUND);
        }
        GetResponse result = this.client.prepareGet("book", "novel", id).get();
        if (!result.isExists())
        {
            return new ResponseEntity(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity(result.getSource(), HttpStatus.OK);
    }
  • 更新操作
@PutMapping("/put/book/novel")
    public ResponseEntity update(@RequestParam(name = "id") String id, @RequestParam(name = "title", required = false) String title,
        @RequestParam(name = "author", required = false) String author
    )
    {
        try {
            XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
            if (title!= null)
            {
                builder.field("title", title);
            }
            if (author != null)
            {
                builder.field("author", author);
            }
            builder.endObject();
            UpdateRequest updateRequest = new UpdateRequest("book", "novel", id);
            updateRequest.doc(builder);

            UpdateResponse result = client.update(updateRequest).get();

            return new ResponseEntity(result.getResult().toString(), HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
  • 复合查找
@GetMapping("/query/book/novel")
    public ResponseEntity query(@RequestParam(name = "author", required = false) String author,
                                     @RequestParam(name = "title", required = false) String title,
                                     @RequestParam(name = "gt_word_count", defaultValue = "0") int gtWordCount,
                                     @RequestParam(name = "lt_word_count", required = false) Integer ltWordCount)
    {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (author != null)
        {
            boolQueryBuilder.must(QueryBuilders.matchQuery("author",author));
        }
        if (title != null)
        {
            boolQueryBuilder.must(QueryBuilders.matchQuery("title", title));
        }

        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("word_count").from(gtWordCount);
        if (ltWordCount != null && ltWordCount > 0)
        {
            rangeQueryBuilder.to(ltWordCount);
        }

        boolQueryBuilder.filter(rangeQueryBuilder);

        SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("book")
                .setTypes("novel")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(boolQueryBuilder)
                .setFrom(0)
                .setSize(10);
        System.out.println(searchRequestBuilder); //调试用

        SearchResponse response = searchRequestBuilder.get();
        List> result = new ArrayList<>();
        for (SearchHit hit : response.getHits())
        {
            result.add(hit.getSource());
        }

        return  new ResponseEntity(result, HttpStatus.OK);
    }

上面的代码组织的复合查询类似下面的Query DSL:

{
    "query":{
        "bool":{
            "must":[
                {"match":{"author":"张三"}},
                {"match":{"title":"Elasticsearch"}}
            ],
            "filter":[
                {"range":
                    {"word_count":{ "gt":"0", "lt":"3000" } }
                }
            ]
        }
    }
}

你可能感兴趣的:(elasticsearch)