spring-data-elasticsearch的模板使用(二)

spring-data-elasticsearch的模板使用(二)

这里讲述java API
这里的导包、配置yml、写实体类与上文的一样,这里忽略。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sinux.springdataelasticsearch.es.entity.Item;
import com.sinux.springdataelasticsearch.es.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * java API操作文档库
 */
@RestController
@RequestMapping("/esclient")
@Api(value = "es的swagger", tags = "es的client操作")
@Slf4j
public class EsClientController {
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 往索引库添加文档信息
     */
    @PostMapping("/save")
    @ApiOperation(value = "往索引库添加文档信息", notes = "往索引库添加文档信息")
    public <T> void save(@RequestBody T t, String index, String type) {
        /**
         * client.prepareIndex 参数可以是零个(其后必须使用 index(String) 和 type(String) 方法)
         * 两个(client.prepareIndex(index,type))和三个(client.prepareIndex(index,type,id)),
         * 其中 index 类似于库名,type 类似于表名(和前面说过的一样),而 id 则是每条记录的惟一编码。
         * 通常情况下我们会把实体的唯一编码作为 es 的 id。如果不给 id 的时候,由 es 自动生成。
         */
        Map<String, Object> sourceMap = ((JSONObject) JSON.toJSON(t)).getInnerMap();
        Client client = elasticsearchTemplate.getClient();
        if (t instanceof Item) {
            Item item = (Item) t;
            client.
                    prepareIndex(index, type, "" + item.getId()).
                    setSource(sourceMap, XContentType.JSON).
                    setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).
                    get();
        } else {
            client.
                    prepareIndex(index, type).
                    setSource(sourceMap, XContentType.JSON).
                    setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).
                    get();
        }

    }


    /**
     * 功能描述: 批量更新
     */
    @PostMapping("/batchupdate")
    @ApiOperation(value = "批量更新", notes = "批量更新")
    public Result batchupdate(@RequestBody List<Item> list) {
        Client client = elasticsearchTemplate.getClient();
        BulkRequestBuilder requestBuilder = client.prepareBulk();
        try {
            list.parallelStream().forEach(es -> {
                Map<String, Object> sourceMap = ((JSONObject) JSON.toJSON(es)).getInnerMap();
                UpdateRequestBuilder updateRequestBuilder = client.
                        prepareUpdate("item", "docs", "" + es.getId()).
                        setDoc(sourceMap, XContentType.JSON);
                if (null != updateRequestBuilder) {
                    requestBuilder.add(updateRequestBuilder);
                }
            });
            requestBuilder.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
            return new Result("批量更新成功!");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("批量更新失败!");
        }
    }

    /**
     * 功能描述: 批量保存数据
     */
    @PostMapping("/batchsave")
    @ApiOperation(value = "批量保存数据", notes = "批量保存数据")
    public Result batchsave(@RequestBody List<Item> list) {
        Client client = elasticsearchTemplate.getClient();
        BulkRequestBuilder requestBuilder = client.prepareBulk();
        try {
            list.parallelStream().forEach(es -> {
                Map<String, Object> sourceMap = ((JSONObject) JSON.toJSON(es)).getInnerMap();
                IndexRequestBuilder indexRequestBuilder = client.
                        prepareIndex("item", "docs", "" + es.getId()).
                        setSource(sourceMap, XContentType.JSON);
                if (null != indexRequestBuilder) {
                    requestBuilder.add(indexRequestBuilder);
                }
                requestBuilder.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
            });
            return new Result("批量插入成功!");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("插入失败!");
        }
    }

    /***
     * 根据id查询
     */
    @PostMapping("/findbyid")
    @ApiOperation(value = "根据id查询", notes = "根据id查询")
    public Result findById(@RequestBody String id) {
        log.info("……………………" + id);
        List<Map<String, Object>> list = new ArrayList<>();
        QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds(id);
        SearchRequestBuilder index = elasticsearchTemplate.getClient().prepareSearch("item").setQuery(queryBuilder).setSize(10);
        SearchHits hits = index.get().getHits();
        for (SearchHit hit : hits) {
            list.add(hit.getSourceAsMap());
        }
        log.info("=====================" + list);
        return new Result(list);
    }

    /***
     * 按指定字段模糊查询
     */
    @PostMapping("/queryindexfield")
    @ApiOperation(value = "按指定字段模糊查询", notes = "按指定字段模糊查询")
    public Result findByField(@RequestBody String brand) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //模糊匹配查询,需要以*号结尾,提高查询效率
        boolQueryBuilder.must(QueryBuilders.regexpQuery("brand", ".*" + brand.toLowerCase() + ".*"));
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).build();
        List<Item> list = elasticsearchTemplate.queryForList(searchQuery, Item.class);
        return new Result(list);
    }

    /**
     * 批量删除
     */
    @PostMapping("/batchdel")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    public Result del(@RequestBody String ids) {
        log.info("===========" + ids);
        String[] id = ids.split(",");
        try {
            for (String Id : id) {
                elasticsearchTemplate.delete(Item.class, Id);
            }
            return new Result("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result("删除失败" + e.getMessage());
        }
    }

    /**
     * multi_match多个字段匹配某字符串,模糊查询
     * 如果我们希望title,content两个字段去匹配某个字符串,只要任何一个字段包括该字符串即可,就可以使用multimatch
     * withPageable:分页
     * int start,起始页,***第一页是start为0***
     * int maxSize,每页条数
     * withSort:排序
     * SortBuilders.fieldSort("id").order(SortOrder.DESC)是id倒序排序,如果是ASC就是升序
     */
    @PostMapping("/multimatch")
    @ApiOperation(value = "多个字段匹配某字符串,模糊查询", notes = "多个字段匹配某字符串,模糊查询")
    public Result multimatch(@RequestBody String keyword,int start,int maxSize) {

        log.info("___________________________________________");
        SearchQuery searchQuery = new NativeSearchQueryBuilder().
                withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "category", "brand")).
                withPageable(PageRequest.of(start,maxSize)).
                withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC)).
                build();
        List<Item> list = elasticsearchTemplate.queryForList(searchQuery, Item.class);

        log.info("===================" + list);
        return new Result(list);
    }
}

总结:
matchQuery:词条匹配,先分词然后在调用termQuery进行匹配
TermQuery:词条匹配,不分词
wildcardQuery:通配符匹配
fuzzyQuery:模糊匹配
rangeQuery:范围匹配
booleanQuery:布尔查询
NativeSearchQueryBuilder:Spring提供的一个查询条件构建器,帮助构建json格式的请求体
QueryBuilders.matchQuery(“title”, “小米手机”):利用QueryBuilders来生成一个查询。QueryBuilders提供了大量的静态方法,用于生成各种不同类型的查询。
BooleanClause用于表示布尔查询子句关系的类,包括:BooleanClause.Occur.MUST,BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.SHOULD。必须包含,不能包含,可以包含三种.有以下6种组合:

1.MUST和MUST:交集。
2.MUST和MUST_NOT:表示查询结果中不能包含MUST_NOT所对应得查询子句的检索结果。
3.SHOULD与MUST_NOT:连用时,功能同MUST和MUST_NOT。
4.SHOULD与MUST连用时,结果为MUST子句的检索结果,但是SHOULD可影响排序。
5.SHOULD与SHOULD:并集。
6.MUST_NOT和MUST_NOT:无意义,检索无结果。

使用QueryBuilder
* termQuery(“key”, obj) 完全匹配
* termsQuery(“key”, obj1, obj2…) 一次匹配多个值
* matchQuery(“key”, Obj) 单个匹配, field不支持通配符, 前缀具高级特性
* multiMatchQuery(“text”, “field1”, “field2”…); 匹配多个字段, field有通配符忒行
* matchAllQuery(); 匹配所有文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神雕大侠mu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值