关于Springboot的ElasticSearch(spring-boot-starter-data-elasticsearch)的配置以及使用

pom

      
            org.springframework.boot
            spring-boot-starter-data-elasticsearch
        

application.properties

spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300

常见问题
为什么要把出现的问题放在这么前面?->
因为版本问题网上挺难找到的,要是版本不对还挺难发现的

  • 1
    报这个错
java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]

解决方法:新建elasticSearch配置类


import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class ElasticSearchConfig {
    /**
     * 防止netty的bug
     * java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]
     */
    @PostConstruct
    void init() {
        System.setProperty("es.set.netty.runtime.available.processors", "false");
    }
}
  • 2
    报这个错
Elasticsearch NoNodeAvailableException None of the configured nodes are available

并且elasticSearch控制台报了这个错

 java.lang.IllegalStateException: Received message from unsupported version: [2.0 .0] minimal compatible version is: [5.0.0] - Stack Overflow

看起来像是说节点没配置,网上找到的大部分方法也是对elasticSearch目录下的elasticSearch.yml进行修改,把对应的port改为127.0.0.1,但是还有另一种可能,
就是jar包冲突。
springboot的版本也与你的elasticSearch的版本息息相关,这里附上来自how2j.cn的版本对应图关于Springboot的ElasticSearch(spring-boot-starter-data-elasticsearch)的配置以及使用_第1张图片

这里有一部分其实是有缺失的,当SpringBoot版本大于2时(我的是2.0.7)已经不能再用2.0.0-5.0.0版本的elasticSearch了,用5以上应该就没问题了,我改用6.2.2就没发生这个错误了。


如何使用
elasticSearch 其实也算是一种nosql数据库,如果是用spring-boot-starter-data-elasticsearch的话在增删方面用起来和JPA几乎没什么两样。

  1. 实体类
package com.how2j.copy.pojo.es;

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


@Document(indexName = "copyhow2j" , type = "course")
public class Course {

private Integer id ;

private String stageName;

private String itemName;

private String itemSubTitle;

private String stepName;

private String title;

private  String content;

}

@Document注解就表明了这是一个ElasticSearch的表
indexName顾名思义就是索引名的意思,不过用起来的话基本可以看作相当于数据库名
而type 则相当于表名
2. Dao层
//如果不适用springboot的方式可不能这么用


/*
和JPA一样 继承一个Repository接口 泛型第一个参数为对应的实体类,第二个为相应的主键
*/
public interface CourseDao extends ElasticsearchRepository {
}

2.2 与JPA不同的地方

  1. 插入时主键不会自增长
    我看有的人是采用当前的时间作为主键的(System.currentTimeMills())
  2. 查找出来的结果返回的不是List而是Iterable
    这里命名有点难受,因为我一开始以为和JPA一样返回的是List,后来才发现不是。。。还没改过来,抱歉了。
   @Override
    public List list() {
        Iterable list = courseDao.findAll();
        List result = new ArrayList<>();
        list.forEach(single -> {
            result.add(single);
        });
        /*
        方法2
         */
//        list.forEach(
//                result::add
//        );
        /*
        或者自己不用Lambda 直接遍历再add也可以
         */
        return result;
    }

3. 查询
    public SearchQuery getSearchQuery(int page , int size , String key,String index, String type){
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.wildcardQuery("content","*"+key+"*"))
                .withIndices(index)
                .withTypes(type)
                .withPageable(PageRequest.of(page,size))
                .build();
    return searchQuery;
    }

查询这方面 姑且还是引用别人的吧,,我只用来做了个模糊查询


词条查询 //根据指定的字段词条查询 (调用文档对象的dao类中的方法,根据名称去抒写功能已经完成,自定义方法)
   @Test
    public void termSearch(){
        List list = itemRepository.findByTitle("高尔夫");

        for (Item t:list
             ) {
            System.out.println(t);
        }
    }

范围查询
//根据指定字段大小范围查询
    @Test
    public void numberSearch(){
        List list = itemRepository.findByPriceBetween(8000.0, 15000.0);

        for (Item b:list
             ) {
            System.out.println(b);
        }
    }

自定义查询(自己构造查询条件,对比基础查询,搜索内容有了条件) term查询
@Test
    public void termSearch1(){
        //创建查询条件生成器 (相当于Lucene中的查询文档对象)
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.termQuery("category","运动品a"));

        //查询到的结果,自动分页,默认第一页,每页条目数是10条(itemRepository相当于文档读取器,参数中的文档查询对象需要构建下)
        //在查询条件生成器中生成查询对象所以去build构建
        Page search = itemRepository.search(nativeSearchQueryBuilder.build());

        for (Item i:search
                ) {
            System.out.println(i);
        }

    }

match匹配查询(相当于词条匹配查询,自定义查询)
@Test
    public void matchSearch(){
        //创建查询条件生成器 (相当于Lucene中的查询文档对象)
       NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
       nativeSearchQueryBuilder.withQuery(QueryBuilders.matchQuery("title","足球"));

       //查询到的结果,自动分页,默认第一页,每页条目数是10条(itemRepository相当于文档读取器,参数中的文档查询对象需要构建下)
       //在查询条件生成器中生成查询对象所以去build构建
       Page search = itemRepository.search(nativeSearchQueryBuilder.build());

       for (Item i:search
            ) {
           System.out.println(i);
       }

   }

布尔查询(综合查询)
 @Test
   public void booleanSearch(){
        //创建查询条件生成器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title","篮球")).must(QueryBuilders.matchQuery("category","运动品a")));

        //查询
       Page search = itemRepository.search(nativeSearchQueryBuilder.build());

       for (Item i:search
            ) {
           System.out.println(i);
       }

   }

容错查询(最多错两个)

@Test
    public void fuzzSearch(){
        //创建查询条件生成器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.fuzzyQuery("title","球"));

        //查询
        Page search = itemRepository.search(nativeSearchQueryBuilder.build());

        for (Item i:search
             ) {
            System.out.println(i);
        }
    }

模糊查询
注意: ? 表示询问一个未知的占位符,* 表示询问0到n个任意占位符

 @Test
    public void wildCardSearch(){
        //创建查询条件生成器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.wildcardQuery("title","*球*"));

        //查询
        Page search = itemRepository.search(nativeSearchQueryBuilder.build());

        for (Item i:search
             ) {
            System.out.println(i);
        }
    }

分页查询(只是在查询条件生成器中多构建了一个分页而已,基于模糊查询的分页)
@Test
    public void feYeSearch(){
        //创建查询条件生成器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.wildcardQuery("title","*球"));

        //构建分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(0,3));

        //查询
        Page search = itemRepository.search(nativeSearchQueryBuilder.build());

        for (Item i:search
             ) {
            System.out.println(i);
        }
    }

排序查询(使查询结果按指定字段排序,基于模糊查询)
@Test
    public void sortSearch(){
        //构建查询条件生成器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.wildcardQuery("title","*球"));

        //构建排序
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));

        //查询
        Page search = itemRepository.search(nativeSearchQueryBuilder.build());

        for (Item i:search
             ) {
            System.out.println(i);

        }

    }

组合模糊查询,分页,排序
@Test
    public void mfpSearch(){
        //创建查询条件构造器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(QueryBuilders.wildcardQuery("title","*球"));

        //构建分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(0,5));

        //构建排序
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));

        //查询
        Page search = itemRepository.search(nativeSearchQueryBuilder.build());

        for (Item i:search
             ) {
            System.out.println(i);
        }

    }

由此可见,查询条件只要不违反规则是可以累加的 下面小熙来介绍elasticsearch最厉害的聚合查询吧,其查询广度、分组处理、度量计算、子聚合(类似于mysql的子查询)是小熙所膜拜的。 单一聚合查询
 @Test
    public void jhSearch(){
        //创建查询条件构造器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        // 不查询任何结果
//        nativeSearchQueryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
        //添加聚合 (此聚合类型为terms,聚合名称是:categorys,聚合字段是category)
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("categorys").field("category"));
        //查询(结果修改为聚合类分页结果)
        AggregatedPage search = (AggregatedPage )itemRepository.search(nativeSearchQueryBuilder.build());

        //结果中找到对应的聚合(根据聚合名称)
        StringTerms category = (StringTerms)search.getAggregation("categorys");
        //获取查询到的桶
        List buckets = category.getBuckets();

        for (StringTerms.Bucket s:buckets
             ) {
            //获取桶中的key(就是字段下的名称)
            String keyAsString = s.getKeyAsString();
            System.out.println( keyAsString);
            //获取桶中的数量(即为查询到的文档数量)
            long docCount = s.getDocCount();
            System.out.println(docCount);
        }

    }

包含子聚合的聚合查询

@Test
    public void jh2Search(){
        //创建查询条件构造器
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand")
                                         //创建子聚合工程(对父聚合工程的结果进行求取平均值)
                                    .subAggregation(AggregationBuilders.avg("avg").field("price"))
        );

        //查询
        AggregatedPage search = (AggregatedPage)itemRepository.search(nativeSearchQueryBuilder.build());
        //根据聚合名称获取对应聚合
        StringTerms brands = (StringTerms)search.getAggregation("brands");
        //获取查询到的桶
        List buckets = brands.getBuckets();

        for (StringTerms.Bucket b:buckets
             ) {
            //获取父聚合的字段名
            System.out.print("品牌名称:"+b.getKeyAsString() + "查到的文档数:"+b.getDocCount());
            //获取父聚合中桶中数量
            System.out.println();
            //获取子聚合,转为Map集合,获取构建子聚合时价格平均值的key,这里指定的是avg(强转为平均值)。
            InternalAvg avg = (InternalAvg)b.getAggregations().asMap().get("avg");
            System.out.println("\t\t平均价格是:"+avg.getValue());
        }

    }

你可能感兴趣的:(配置,一般男性黄黄黄个人用)