精华内容
下载资源
问答
  • SpringBoot整合elasticsearch pom引入 <!--elasticsearch--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch<...

    我的开源微服务前后端分离博客项目地址,欢迎各位star

    博主技术文档地址

    欢迎大家进群,一起讨论学习

    欢迎大家进群,一起讨论学习

    SpringBoot整合elasticsearch

    pom引入

    <!--elasticsearch-->
     	<parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
     <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.8.6</version>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    

    yml配置

    spring:
      data:
      elasticsearch:
        rest:
          uris: ["ip:9200"]
        elasticsearch:
          cluster-name: docker-cluster
          cluster-nodes: ip:9300 #配置es节点信息,逗号分隔,如果没有指定,则启动ClientNode
          properties:
            path:
              logs: ./elasticsearch/log #elasticsearch日志存储目录
              data: ./elasticsearch/data #elasticsearch数据存储目录
    
    

    配置只需这么些,接下来就写一些demo来玩一下elaseticsearch

    构建Item类

    @Document(indexName = "item",type = "docs", shards = 1, replicas = 0)
    public class Item {
        @Id
        private Long id;
        //文章使用分词器
        @Field(type = FieldType.Text, analyzer = "ik_max_word")
        private String title; //标题
        @Field(type = FieldType.Keyword)
        private String category;// 分类
        @Field(type = FieldType.Keyword)
        private String brand; // 品牌
        @Field(type = FieldType.Double)
        private Double price; // 价格
        
    }
    

    创建ItemRepository并继承ElasticsearchRepository,有兴趣的可以看一下底层源码

    public interface ItemRepository extends ElasticsearchRepository<Item,Long>{
        /**
         * @Description:根据价格区间查询  自定义查询
         * @Param price1
         * @Param price2
         */
        List<Item> findByPriceBetween(double price1, double price2);
     
        List<Item> findByTitle(String title1);
     
        List<Item> findByTitleIn(Collection<String> ss);
    }
    

    创建索引

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = BootApplication.class)
    public class EsDemoApplicationTest{
        @Autowired
        private ElasticsearchRestTemplate elasticsearchRestTemplate;
     
     
        /**
         * @Description:创建索引,会根据Item类的@Document注解信息来创建
         */
        @Test
        public void testCreateIndex() {
           elasticsearchRestTemplate.indexOps(Item.class).create();
        }
     
        /**
         * @Description:删除索引
         */
        @Test
        public void testDeleteIndex() {
            elasticsearchRestTemplate.indexOps(Item.class).delete();
        }
    	/**
         * @Description:判断索引是否存在
         */
        @Test
        public void testExistIndex() {
            elasticsearchRestTemplate.indexOps(Item.class).exists();
        }
        /**
         * @Description:删除
         */
        @Test
        public void delete() {
            elasticsearchRestTemplate.delete(1L, Item.class);
        }
        /**
         * 查询文档数据
         */
        @Test
        public void getDoc() {
            Item item = elasticsearchRestTemplate.get(String.valueOf(1L), Item.class);
            System.out.println(item);
        }
    
        /**
         * 修改文档数据
         */
        @Test
        public void updateDoc() {
    
            Map<String, Object> map = new HashMap<>();
            map.put("title", "abc");
    
            Document doc = Document.from(map);
    
            UpdateQuery updateQuery = UpdateQuery
                    .builder(String.valueOf(1))
                    .withDocument(doc)
                    .build();
            IndexCoordinates indexCoordinates = IndexCoordinates.of("item");
            elasticsearchRestTemplate.update(updateQuery, indexCoordinates);
        }
    
        /**
         * 分页搜索数据
         * 使用QueryBuilder
         * termQuery("key", obj) 完全匹配
         * termsQuery("key", obj1, obj2..)   一次匹配多个值
         * matchQuery("key", Obj) 单个匹配, field不支持通配符, 前缀具高级特性
         * multiMatchQuery("text", "field1", "field2"..);  匹配多个字段, field有通配符忒行
         * matchAllQuery();         匹配所有文件
         * idsQuery();         只查询一个id的
         * fuzzyQuery();          模糊查询 不能用通配符, 找到相似的
         */
        @Test
        public void search() {
            Pageable pageable = PageRequest.of(0, 10);
    
            SortBuilder<FieldSortBuilder> sortBuilder = new FieldSortBuilder("price")
                    .order(SortOrder.DESC);
    
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(QueryBuilders.boolQuery().should(QueryBuilders.fuzzyQuery("title", "360")))
                    .withPageable(pageable)
                    .withSort(sortBuilder)
                    .build();
            SearchHits<Item> search = elasticsearchRestTemplate.search(query, Item.class);
            System.out.println(search.getSearchHits());
        }
    
        /**
         * 高亮搜索
         */
        @Test
        public void highlight() {
            String preTag = "<font color='red'>";
            String postTag = "</font>";
    
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(QueryBuilders.matchQuery("title", "360"))
                    .withHighlightFields(new HighlightBuilder.Field("title")
                            .preTags(preTag)
                            .postTags(postTag))
                    .build();
            SearchHits<Item> searchHits = elasticsearchRestTemplate.search(query, Item.class);
    
            List<SearchHit<Item>> searchHitList = searchHits.getSearchHits();
            List<Map<String, Object>> hlList = new ArrayList<>();
            for (SearchHit h : searchHitList) {
    
                List<String> highlightField = h.getHighlightField("title");
                String nameValue = highlightField.get(0);
                String originalJson = JSON.toJSONString(h.getContent());
                JsonParser jj = new GsonJsonParser();
                Map<String, Object> myHighLight = jj.parseMap(originalJson);
                // 用高亮的搜索结果覆盖原字段值
                myHighLight.put("title", nameValue);
                System.out.println(myHighLight);
    
                hlList.add(myHighLight);
            }
            System.out.println(hlList);
        }
        /**
         * 高亮搜索 排序加分页
         */
        @Test
        public void highlight1() {
            String preTag = "<font color='red'>";
            String postTag = "</font>";
            Pageable pageable = PageRequest.of(0, 10);
            SortBuilder<FieldSortBuilder> sortBuilder = new FieldSortBuilder("price")
                    .order(SortOrder.DESC);
            NativeSearchQuery query = new NativeSearchQueryBuilder()
                    .withQuery(QueryBuilders.fuzzyQuery("title", "360"))
                    .withPageable(pageable)
                    .withSort(sortBuilder)
                    .withHighlightFields(new HighlightBuilder.Field("title")
                            .preTags(preTag)
                            .postTags(postTag))
                    .build();
            SearchHits<Item> searchHits = elasticsearchRestTemplate.search(query, Item.class);
    
            List<SearchHit<Item>> searchHitList = searchHits.getSearchHits();
            List<Map<String, Object>> hlList = new ArrayList<>();
            for (SearchHit h : searchHitList) {
    
                List<String> highlightField = h.getHighlightField("title");
                String nameValue = highlightField.get(0);
                String originalJson = JSON.toJSONString(h.getContent());
                JsonParser jj = new GsonJsonParser();
                Map<String, Object> myHighLight = jj.parseMap(originalJson);
                // 用高亮的搜索结果覆盖原字段值
                myHighLight.put("title", nameValue);
                hlList.add(myHighLight);
            }
            System.out.println(hlList);
        }
    }
    

    QueryBuilder构造ES查询条件使用规则

    https://blog.csdn.net/csdn_20150804/article/details/105618933

    第二种实现方式 RestHighLevelClient

    package comn.hy.search.service.impl;
     
     
    import com.hy.search.Stu;
    import com.hy.utils.JsonUtils;
    import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
    import org.elasticsearch.action.bulk.BulkRequest;
    import org.elasticsearch.action.bulk.BulkResponse;
    import org.elasticsearch.action.delete.DeleteRequest;
    import org.elasticsearch.action.delete.DeleteResponse;
    import org.elasticsearch.action.get.GetRequest;
    import org.elasticsearch.action.get.GetResponse;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.index.IndexResponse;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.action.support.master.AcknowledgedResponse;
    import org.elasticsearch.action.update.UpdateRequest;
    import org.elasticsearch.action.update.UpdateResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.client.indices.CreateIndexRequest;
    import org.elasticsearch.client.indices.CreateIndexResponse;
    import org.elasticsearch.client.indices.GetIndexRequest;
    import org.elasticsearch.common.unit.TimeValue;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.elasticsearch.index.query.TermQueryBuilder;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
    import org.springframework.web.bind.annotation.*;
     
    import javax.annotation.Resource;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.concurrent.TimeUnit;
    @RestController
    public class TestServiceES {
     
        @Resource
        private RestHighLevelClient client;
     
     
        /**
         * 创建索引
         * @throws IOException
         */
        @PostMapping("create-index")
        public void createIndex() throws IOException {
            CreateIndexRequest request = new CreateIndexRequest("user_index");
            CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
            System.out.println(response);
        }
     
        /**
         * 获取索引信息
         * @throws IOException
         */
        @GetMapping("query-index")
        public void queryIndex() throws IOException {
            GetIndexRequest request = new GetIndexRequest("user_index");
     
            boolean b = client.indices().exists(request, RequestOptions.DEFAULT);
            System.out.println(b);
        }
     
     
        /**
         * 删除索引
         * @throws IOException
         */
       @DeleteMapping("delete-index")
        public void deleteIndex() throws IOException {
            DeleteIndexRequest request = new DeleteIndexRequest("user_index");
            AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
            System.out.println(delete.isAcknowledged());
        }
     
        /**
         * 新增一个文档
         * @throws IOException
         */
        @PostMapping("add-doc")
        public void addDoc() throws IOException {
     
            Stu stu = new Stu(10010L, "绝世风华", 18, 100.5f, true);
            IndexRequest request = new IndexRequest("user_index");
            // 规则 put /test_index/_doc/1
            request.id("1");
            request.timeout(new TimeValue(60, TimeUnit.SECONDS));
            request.source(JsonUtils.objectToJson(stu),XContentType.JSON);
            // 发送
            IndexResponse response = client.index(request,RequestOptions.DEFAULT);
            System.out.println(response.toString());
            System.out.println(response.status());
        }
     
        /**
         * 查询文档数据
         * @throws IOException
         */
        @GetMapping("query-doc")
        void queryDoc() throws IOException {
            GetRequest request = new GetRequest("user_index","1");
            request.fetchSourceContext(new FetchSourceContext(false));
            request.storedFields("_none_");
     
            // 是否存在???
            boolean b = client.exists(request,RequestOptions.DEFAULT);
            System.out.println(b);
     
            // 获取
            GetResponse response = client.get(request,RequestOptions.DEFAULT);
            System.out.println(response.getSourceAsString());
            System.out.println(response);
        }
     
        /**
         * 更新文檔
         * @throws IOException
         */
        @PutMapping("update-doc")
        public void updateDoc() throws IOException {
            UpdateRequest updateRequest = new UpdateRequest("user_index","1");
            updateRequest.timeout("1s");
            Stu stu = new Stu(10010L, "上善若水", 18, 100.5f, true);
            updateRequest.doc(JsonUtils.objectToJson(stu),XContentType.JSON);
     
            UpdateResponse response = client.update(updateRequest,RequestOptions.DEFAULT);
     
            System.out.println(response);
            System.out.println(response.status());
        }
     
        /**
         * 删除文档
         * @throws IOException
         */
        @DeleteMapping("delete-doc")
        public void deleteDoc() throws IOException {
            DeleteRequest deleteRequest = new DeleteRequest("user_index","1");
            deleteRequest.timeout("1s");
            DeleteResponse response = client.delete(deleteRequest,RequestOptions.DEFAULT);
            System.out.println(response);
            System.out.println(response.status());
        }
     
     
     
        /**
         * 批量操作
         * @throws IOException
         */
        @PostMapping("bulk-operator")
        public void bulkOperator() throws IOException {
            BulkRequest bulkRequest = new BulkRequest();
            bulkRequest.timeout("15s");
     
            Stu stu0 = new Stu(10010L, "诸天万界之起源传说", 18, 100.5f, true);
            Stu stu1 = new Stu(10011L, "寒夜", 20, 88.5f, true);
            Stu stu2 = new Stu(10012L, "陌上千寻雪", 22, 96.5f, false);
            Stu stu3 = new Stu(10013L, "可爱的漂亮的小哥哥", 26, 108.5f, false);
            Stu stu4 = new Stu(10014L, "灵纪传说", 28, 108.6f, true);
            Stu stu5 = new Stu(10015L, "狂剑天下之鸿蒙掌控", 16, 18.5f, false);
            Stu stu6 = new Stu(10016L, "逆战次元", 29, 100.5f, true);
     
            ArrayList<Stu> stuList = new ArrayList<>();
            stuList.add(stu0);
            stuList.add(stu1);
            stuList.add(stu2);
            stuList.add(stu3);
            stuList.add(stu4);
            stuList.add(stu5);
            stuList.add(stu6);
     
            for(int i = 0;i<=stuList.size();i++){
                bulkRequest.add(
                        new IndexRequest("test.index").
                                id(""+(i+1)).
                                source(JsonUtils.objectToJson(stuList.get(i)), XContentType.JSON));
            }
            // 批量插入
            BulkResponse response = client.bulk(bulkRequest,RequestOptions.DEFAULT);
            System.out.println(response.hasFailures());
        }
     
     
        /**
         * 条件查询
         * @throws IOException
         */
        @GetMapping("condition-search")
        public void conditionSearch() throws IOException {
            SearchRequest searchRequest = new SearchRequest("user_index");
            // 构造条件
            SearchSourceBuilder builder = new   SearchSourceBuilder();
            // 精确匹配
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name","绝世风华");
     
            // 匹配全部 matchAllQuery();
            builder.query(termQueryBuilder);
     
            // 分页
            builder.from(0);
            builder.size(10);
            builder.timeout(TimeValue.MINUS_ONE);
            searchRequest.source(builder);
            SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
            System.out.println(JsonUtils.objectToJson(response.getHits()));
     
            for (org.elasticsearch.search.SearchHit hit : response.getHits().getHits()) {
                hit.getSourceAsMap().get("name");
            }
        }
     
     
    }
     
    

    先执行创建索引在这里插入图片描述
    索引数据操作

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = BootApplication.class)
    public class ceshiTest {
        @Autowired
        private ItemRepository itemRepository;
     
        /**
         * @Description:定义新增方法
         */
        @Test
        public void insert() {
            Item item = new Item(1L, "小米手机7", " 手机",
                    "小米", 3499.00);
            itemRepository.save(item);
        }
     
     
     
        /**
         * @Description:定义批量新增方法
         */
        @Test
        public void insertList() {
            List<Item> list = new ArrayList<>();
            list.add(new Item(1L, "小米9", "手机", "小米", 3299.00));
            list.add(new Item(2L, "华为pro30", "手机", "华为", 3999.00));
            list.add(new Item(3L, "一加7", "手机", "一加", 2999.00));
            list.add(new Item(4L, "魅族16", "手机", "魅族", 1999.00));
            list.add(new Item(5L, "苹果xs", "手机", "苹果", 5099.00));
            list.add(new Item(6L, "360pro", "手机", "360", 1099.00));
            list.add(new Item(7L, "荣耀V10", "手机", "华为", 899.00 ));
            // 接收对象集合,实现批量新增
            itemRepository.save(list);
        }
        
    
        
        /**
         * @Description:按照价格区间查询  自定义方法
         * 自定义方法
            Spring Data 的另一个强大功能,是根据方法名称自动实现功能。
            比如:你的方法名叫做:findByTitle,那么它就知道你是根据title查询,然后自动帮你完成,无需写实现类。
            当然,方法名称要符合一定的约定  下边为约定
                And	findByNameAndPrice
                Or	findByNameOrPrice
                Is	findByName
                Not	findByNameNot
                Between	findByPriceBetween
                LessThanEqual	findByPriceLessThan
                GreaterThanEqual	findByPriceGreaterThan
                Before	findByPriceBefore
                After	findByPriceAfter
                Like	findByNameLike
                StartingWith	findByNameStartingWith
                EndingWith	findByNameEndingWith
                Contains/Containing	findByNameContaining
                In	findByNameIn(Collection<String>names)
                NotIn	findByNameNotIn(Collection<String>names)
                Near	findByStoreNear
                True	findByAvailableTrue
                False	findByAvailableFalse
                OrderBy	findByAvailableTrueOrderByNameDesc
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void queryByPriceBetween(){
            List<Item> list = this.itemRepository.findByPriceBetween(2000.00, 3500.00);
            for (Item item : list) {
                System.out.println("item = " + item.getTitle());
            }
        }
     
     
        @Test
        public void queryByTitle(){
            List<Item> list = this.itemRepository.findByTitle("华为");
            for (Item item : list) {
                System.out.println("item = " + item.getTitle());
            }
        }
     
        @Test
        public void queryByTitleTo(){
            Collection<String> ss =  new ArrayList<>();
            ss.add("华为");
            ss.add("小米");
            List<Item> list = this.itemRepository.findByTitleIn(ss);
            for (Item item : list) {
                System.out.println("item = " + item.getTitle());
            }
        }
     
        /**
         * @Description:matchQuery底层采用的是词条匹配查询
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testMatchQuery(){
            // 构建查询条件
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
            // 添加基本分词查询
            queryBuilder.withQuery(QueryBuilders.matchQuery("title", "华为"));
            // 搜索,获取结果
            Page<Item> items = this.itemRepository.search(queryBuilder.build());
            // 总条数
            long total = items.getTotalElements();
            System.out.println("获取的总条数 = " + total);
            for (Item item : items) {
                System.out.println("手机名称是:"+item.getTitle());
            }
        }
     
     
        /**
         * @Description:
         * termQuery:功能更强大,除了匹配字符串以外,还可以匹配
         * int/long/double/float/....
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testTermQuery(){
            NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
            builder.withQuery(QueryBuilders.termQuery("price",1099));
            // 查找
            Page<Item> page = this.itemRepository.search(builder.build());
     
            for(Item item:page){
                System.out.println("手机是:"+item.getTitle());
            }
        }
        /**
         * @Description:布尔查询  多条件查询
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testBooleanQuery(){
            NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
     
            builder.withQuery(
                    QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title","华为"))
                            .must(QueryBuilders.matchQuery("brand","华为"))
            );
     
            // 查找
            Page<Item> page = this.itemRepository.search(builder.build());
            for(Item item:page){
                System.out.println("手机名称是"+item.getTitle());
            }
        }
     
     
        /**
         * @Description:布尔查询  多条件查询
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testBlQuery(){
            NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
     
            builder.withQuery(
                    QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title","荣耀"))
                            .must(QueryBuilders.matchQuery("title","华为"))
            );
     
            // 查找
            Page<Item> page = this.itemRepository.search(builder.build());
            for(Item item:page){
                System.out.println("手机名称是"+item.getTitle());
            }
        }
        /**
         * @Description:模糊查询
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testFuzzyQuery(){
            NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
            builder.withQuery(QueryBuilders.fuzzyQuery("title","一"));
            Page<Item> page = this.itemRepository.search(builder.build());
            for(Item item:page){
                System.out.println("手机名称是:"+item.getTitle());
            }
     
        }
     
        /**
         * @Description:分页查询
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void searchByPage(){
            // 构建查询条件
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
            // 添加基本分词查询
            queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
            // 分页:
            int page = 0;
            int size = 2;
            queryBuilder.withPageable(PageRequest.of(page,size));
     
            // 搜索,获取结果
            Page<Item> items = this.itemRepository.search(queryBuilder.build());
            // 总条数
            long total = items.getTotalElements();
            System.out.println("总条数 = " + total);
            // 总页数
            System.out.println("总页数 = " + items.getTotalPages());
            // 当前页
            System.out.println("当前页:" + items.getNumber());
            // 每页大小
            System.out.println("每页大小:" + items.getSize());
     
            for (Item item : items) {
                System.out.println(item.getTitle());
            }
        }
     
        /**
         * @Description:排序查询
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void searchAndSort(){
            // 构建查询条件
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
            // 添加基本分词查询
            queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
     
            // 排序
            queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
     
            // 搜索,获取结果
            Page<Item> items = this.itemRepository.search(queryBuilder.build());
            // 总条数
            long total = items.getTotalElements();
            System.out.println("总条数 = " + total);
     
            for (Item item : items) {
                System.out.println("手机的价格是:"+item.getTitle()+":"+item.getPrice());
            }
        }
     
        /**
         * @Description:按照品牌brand进行分组
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testAgg(){
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
            // 不查询任何结果
            queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
            // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
            queryBuilder.addAggregation(
                    AggregationBuilders.terms("brands").field("brand"));
            // 2、查询,需要把结果强转为AggregatedPage类型
            AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
            // 3、解析
            // 3.1、从结果中取出名为brands的那个聚合,
            // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
            StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
            // 3.2、获取桶
            List<StringTerms.Bucket> buckets = agg.getBuckets();
            // 3.3、遍历
            for (StringTerms.Bucket bucket : buckets) {
                // 3.4、获取桶中的key,即品牌名称
                System.out.println(bucket.getKeyAsString());
                // 3.5、获取桶中的文档数量
                System.out.println(bucket.getDocCount());
            }
     
        }
     
     
        /**
         * @Description:嵌套聚合,求平均值
         * @Author: https://blog.csdn.net/chen_2890
         */
        @Test
        public void testSubAgg(){
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
            // 不查询任何结果
            queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
            // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
            queryBuilder.addAggregation(
                    AggregationBuilders.terms("brands").field("brand")
                            .subAggregation(AggregationBuilders.avg("priceAvg").field("price")) // 在品牌聚合桶内进行嵌套聚合,求平均值
            );
            // 2、查询,需要把结果强转为AggregatedPage类型
            AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
            // 3、解析
            // 3.1、从结果中取出名为brands的那个聚合,
            // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
            StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
            // 3.2、获取桶
            List<StringTerms.Bucket> buckets = agg.getBuckets();
            // 3.3、遍历
            for (StringTerms.Bucket bucket : buckets) {
                // 3.4、获取桶中的key,即品牌名称  3.5、获取桶中的文档数量
                System.out.println(bucket.getKeyAsString() + ",共" + bucket.getDocCount() + "台");
     
                // 3.6.获取子聚合结果:
                InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("priceAvg");
                System.out.println("平均售价:" + avg.getValue());
            }
     
        }
    }
    
    展开全文
  • TermVectorsRequest request = new TermVectorsRequest(index, indexType, id);request.setFields("content");request.setFieldStatistics(true);request.setTermStatistics(true);request.setPositions(true);...

    TermVectorsRequest request = new TermVectorsRequest(index, indexType, id);

    request.setFields("content");

    request.setFieldStatistics(true);

    request.setTermStatistics(true);

    request.setPositions(true);

    request.setOffsets(true);

    request.setPayloads(false);

    Map filterSettings = new HashMap<>();

    filterSettings.put("max_num_terms", 10);//词云数量

    filterSettings.put("min_term_freq", 2);//在当前文档词的频率

    filterSettings.put("max_term_freq", 100);

    filterSettings.put("min_doc_freq", 1);//索引中有几个记录出现

    filterSettings.put("max_doc_freq", 100);

    filterSettings.put("min_word_length", 2);

    filterSettings.put("max_word_length", 10);

    request.setFilterSettings(filterSettings);

    TermVectorsResponse response = elasticsearchTemplate.getClient().termvectors(request, RequestOptions.DEFAULT);

    List termVectorList = response.getTermVectorsList();

    for (TermVectorsResponse.TermVector termVector : termVectorList) {

    String fieldName = termVector.getFieldName();

    TermVectorsResponse.TermVector.FieldStatistics fieldStatistics = termVector.getFieldStatistics();

    List terms = termVector.getTerms();

    for (TermVectorsResponse.TermVector.Term term : terms) {

    //+ "--" + term.getTokens()

    System.out.println("----term:" + term.getTerm() + "  -DocFreq:" + term.getDocFreq() + "  -TermFreq:" + term.getTermFreq());

    //term.getTokens().forEach(s -> System.out.println("----" + s.));

    }

    }

    展开全文
  • 二、问题在做一个需求的时候,需要按照电话号码查询用户关系,所以我这边先讲相关信息同步到es,但是电话号码是加密的,所以显示的字符串是杂乱的,既有字母,又有斜杠等号等字符,在进行分词查询的时候匹配不到相应...

    二、问题

    在做一个需求的时候,需要按照电话号码查询用户关系,所以我这边先讲相关信息同步到es,但是电话号码是加密的,所以显示的字符串是杂乱的,既有字母,又有斜杠等号等字符,在进行分词查询的时候匹配不到相应的数据,所以需要对电话号码字段指定为不分词的查询即完全匹配

    三、解决

    import org.springframework.data.annotation.Id;

    import org.springframework.data.elasticsearch.annotations.Document;

    import org.springframework.data.elasticsearch.annotations.Field;

    import org.springframework.data.elasticsearch.annotations.FieldIndex;

    @Document(indexName = "address_index",type = "t_address")

    public class Address{

    @Id

    private Long id ;

    private String address;

    private String province;

    private String city;

    //@Field(type = FieldType.String , index = FieldIndex.not_analyzed)

    @Field(index = FieldIndex.not_analyzed)

    private String mobile;

    public static long getSerialVersionUID() {

    return serialVersionUID;

    }

    public Long getId() {

    return id;

    }

    public void setId(Long id) {

    this.id = id;

    }

    public String getAddress() {

    return address;

    }

    public void setAddress(String address) {

    this.address = address;

    }

    public String getProvince() {

    return province;

    }

    public void setProvince(String province) {

    this.province = province;

    }

    public String getCity() {

    return city;

    }

    public void setCity(String city) {

    this.city = city;

    }

    public String getMobile() {

    return mobile;

    }

    public void setMobile(String mobile) {

    this.mobile = mobile;

    }

    在代码中指定某个字段不进行分词搜索时候,需要对其类型进行指定,否则查看索引如下图

    not_analyzed.png

    如果指定了字段类型,并且该字段不进行分词搜索,则可以看到其index为not_analyzed

    analyzed.png

    四、es后台管理使用遇到的问题

    {

    "query": {

    "bool": {

    "filter": {

    "terms": {

    "userNo": ["5832794"]

    }

    }

    }

    }

    }

    image.png

    记住这里的查询,方法提交方式是POST、POST、POST

    展开全文
  • 一、问题 在做一个需求的时候,需要按照电话号码查询用户关系,所以我这边先讲相关信息同步到es,但是电话号码是加密的,所以显示的字符串是杂乱的,既有字母,又有斜杠等号等字符,在进行分词查询的时候匹配不到...

    1f22c44965ead193cace85974e17d908.png

    一、问题

    在做一个需求的时候,需要按照电话号码查询用户关系,所以我这边先讲相关信息同步到es,但是电话号码是加密的,所以显示的字符串是杂乱的,既有字母,又有斜杠等号等字符,在进行分词查询的时候匹配不到相应的数据,所以需要对电话号码字段指定为不分词的查询即完全匹配

    二、解决

    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldIndex;
    
    
    @Document(indexName = "address_index",type = "t_address")
    public class Address{
      
        @Id
        private Long id ;
    
        private String address;
    
        private String province;
    
        private String city;
    
        //@Field(type = FieldType.String , index = FieldIndex.not_analyzed)
        @Field(index = FieldIndex.not_analyzed)
        private String mobile;
    
        public static long getSerialVersionUID() {
            return serialVersionUID;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getProvince() {
            return province;
        }
    
        public void setProvince(String province) {
            this.province = province;
        }
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getMobile() {
            return mobile;
        }
    
        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

    在代码中指定某个字段不进行分词搜索时候,需要对其类型进行指定,否则查看索引如下图

    5c626b14ce8442c93d2ad97fb013c643.png

    如果指定了字段类型,并且该字段不进行分词搜索,则可以看到其index为not_analyzed

    606743fde454a2705a0993d1668cfb87.png

    三、es后台管理使用遇到的问题

    {
        "query": {
            "bool": {
                "filter": {
                    "terms": {
                        "userNo": ["5832794"]
                    }
                }
            }
        }
    }

    11354ae0255948e6e76cc1d840160400.png

    这里查询方法提交方式是POST、POST、POST

    展开全文
  • Spark 整合ElasticSearch因为做资料搜索用到了ElasticSearch,最近又了解一下 Spark ML,先来演示一个Spark 读取/写入 ElasticSearch 简单示例。(spark 读取ElasticSearch中数据)环境:IDEA2016,JDK8,windows10,...
  • ElasticSearch JavaAPI 2 初识ElasticSearch 2.1 基于数据库查询的问题 数据库搜索存在问题:性能较低、功能比较弱 2.2 倒排索引 倒排索引:将文档进行分词,形成词条和id的对应关系即为反向索引。 以唐诗为例,...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 216
精华内容 86
关键字:

java整合es

java 订阅