Elasticsearch学习(3) spring boot整合Elasticsearch的原生方式

前面我们已经介绍了spring boot整合Elasticsearch的jpa方式,这种方式虽然简便,但是依旧无法解决我们较为复杂的业务,所以原生的实现方式学习能够解决这些问题,而原生的学习方式也是Elasticsearch聚合操作的一个基础。

一、修改spring boot 的application.properties配置文件

 

##端口号
server.port=8880
##es地址
spring.data.elasticsearch.cluster-nodes =127.0.0.1:9300

 

      需要注意的是:如果你的项目中只配置了Elasticsearch的依赖或者是其他nosql的依赖,那么就要在spring boot启动类中添加@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})注解,这个操作是关闭自动配置数据源文件信息。

 

二、创建一个Bean层

  和spring boot的jpa方式一样,我们需要创建一个bean来作为我们的索引,注意indexName和type的值是你需要查找的索引内容。 

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

@Document(indexName = "article",type = "center")
public class Zoo {
            private int id;
            private String animal;
            private Integer num;
            private String  breeder;
            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            public String getAnimal() {
                return animal;
            }
            public void setAnimal(String animal) {
                this.animal = animal;
            }
            public Integer getNum() {
                return num;
            }
            public void setNum(Integer num) {
                this.num = num;
            }
            public String getBreeder() {
                return breeder;
            }
            public void setBreeder(String breeder) {
                this.breeder = breeder;
            }
            public Zoo(int id, String animal, Integer num, String breeder) {
                super();
                this.id = id;
                this.animal = animal;
                this.num = num;
                this.breeder = breeder;
            }
            public Zoo() {
                super();
            }
            
}
bean层代码

三、创建一个dao层

   创建的dao层中不需要我们写实现的方法,只需要继承ElasticsearchRepository接口。

import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;


@Configuration
public interface ZooMapper  extends  ElasticsearchRepository<Zoo,Integer>{

}
dao层代码

四、创建一个Controller层,编写原生代码

  一般来说这个操作规范下应该写到service层,由于是测试项目,我就直接写在了controller中,我们直接看一个例子

import java.util.List;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class UserController {

    @Autowired
    ZooMapper zooMapper;
    
     // 访问接口地址:localhost:8880/find    
    //存储数据
    @GetMapping("find")
    public Object save(){
        
            //1.创建QueryBuilder  可以理解为装查询条件的容器
             BoolQueryBuilder builder = QueryBuilders.boolQuery();
             //2.设置查询条件,参数1:  字段名 参数2:字段值(为什么中文是一个字而不是词,这个后面在说)
             QueryBuilder queryBuilder1=QueryBuilders.termQuery("breeder", "饲");
             //设置查询条件多个匹配,参数1:  字段名     参数2:字段值  参数3:字段值
             QueryBuilder queryBuilder2=QueryBuilders.termsQuery("animal", "rabbit","lion");
             
             
             //3.将查询的条件放入容器中
             //其中 must相当于SQL中的and     should相当于SQL中的or  mustNot相当于SQL中的not
             builder.must(queryBuilder1);
             builder.should(queryBuilder2);
             
             
             //4.设置排序  参数:需要排序字段 DESC表示降序
             FieldSortBuilder sort = SortBuilders.fieldSort("id").order(SortOrder.DESC);
             
            //5.设置分页,参数1:第几页开始(第一页是0),参数2:显示的条数 
            //在spring 2.0开始后,使用PageRequest.of创建分页参数
             PageRequest page =PageRequest.of(0, 2);
            
             
             //6.在设置好查询条件、排序设置、分页设置后需要将他们放入NativeSearchQueryBuilder 容器中
             NativeSearchQueryBuilder  nativeSearchQueryBuilder =new NativeSearchQueryBuilder();
             //将查询条件放入容器中
             nativeSearchQueryBuilder.withQuery(builder);
             //将分页放入容器中
             nativeSearchQueryBuilder.withPageable(page);
             //将排序放入容器中
             nativeSearchQueryBuilder.withSort(sort);
             //最后将容器组装后,生产NativeSearchQuery
             //此时 SearchQuery中的sql为
             //select  * from zoo where  breeder="饲养员1号" or animal in("rabbit","lion") ORDER BY id DESC LIMIT 0,2
             SearchQuery  query = nativeSearchQueryBuilder.build();
             System.out.println("查询的语句:" + query.getQuery().toString());
             //7.开始查询
             Page<Zoo> listPage = zooMapper.search(query); 
             //获取总条数
             int total = (int) listPage.getTotalElements();
             //获取查询的内容
             List<Zoo> relist = listPage.getContent();
             System.out.println("relist----------------"+relist.toString());
               return relist;
    }
    
    
}
controller层代码

 在测试之前,我们需要在Elasticsearch中添加一个索引,这个索引和我们刚才创建的bean中配置的indexName和type的值一致。

 打开 http://localhost:8888/find,测试我们的代码:

  

  这样做原生的实现方式就已经成功了,接下来就将具体介绍代码中的具体步骤

六、查询条件的具体步骤 

  这一节主要讲解查询条件的具体功能,在controller中,有这样一段代码: 

             //2.设置查询条件,参数1:  字段名 参数2:字段值(为什么中文是一个字而不是词,这个后面在说)
             QueryBuilder queryBuilder1=QueryBuilders.termQuery("breeder", "饲");
             //设置查询条件多个匹配,参数1:  字段名     参数2:字段值  参数3:字段值
             QueryBuilder queryBuilder2=QueryBuilders.termsQuery("animal", "rabbit","lion");

  在这个步骤我们可以看到breeder的值是中文且中文是一个字而不是词,这是因为没有使用分词器的原因,Elasticsearch默认的分片是将中文分解成一个字,英文是单个单词:

   1 设置查询条件

//不分词查询 参数1: 字段名,参数2:字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
  QueryBuilder queryBuilder=QueryBuilders.termQuery("breeder", "饲");
//分词查询,采用默认的分词器
  QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("breeder", "饲养");
//多个匹配的不分词查询
  QueryBuilder queryBuilder=QueryBuilders.termsQuery("animal", "rabbit","lion");
//多个匹配的分词查询
  QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("animal", "r", "l");
//匹配所有文件,相当于就没有设置查询条件
  QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();

 2模糊查询

    除了设置普通的查询,elasticsearch还为我们封装了模糊查询

                //1.常用的字符串查询
                //相当于sql中的  breeder like "饲"
                QueryBuilders.queryStringQuery("饲").field("breeder");
                //2.推荐与该文档相识的文档
                //参数1:字段名 参数2:文档内容
                //如果不指定第一个参数,则默认全部,这个是主要用来推荐偏好内容
                QueryBuilders.moreLikeThisQuery(new String[] {"animal"}).addLikeText("rabbit");
                //3.分词的字段片查询,比如饲养员1号能够被中文分词器分为:饲养员  1 号
                //使用下面的方法就能查询‘饲养员’这个片段,如果没有配置分词器,就查询全部
                QueryBuilders.prefixQuery("breeder","饲养员 ");
                //4.通配符查询,支持* 任意字符串;?任意一个字符与sql中的? *类似
                //参数1:字段名 参数2字段值
                QueryBuilders.wildcardQuery("animal","r??b*");

  在第二条偏好文档设置中有一个偏好的权重问题,如果感兴趣可以参考这个博客:https://blog.csdn.net/laigood/article/details/7831713

 3 逻辑查询 

                //闭区间   相当于id>=2 and id<=5
                QueryBuilder queryBuilder0 = QueryBuilders.rangeQuery("id").from("2").to("5");
                //开区间   相当于id>2 and id<5
                //至于后面两个参数的值默认为true也就是闭区间
                //如果想半开半闭只需要调整后面两个参数的值即可
                QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("id").from("2").to("5").includeUpper(false).includeLower(false);
                //大于   id>2
                QueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("id").gt("2");
                //大于等于  id>=2
                QueryBuilder queryBuilder3 = QueryBuilders.rangeQuery("id").gte("2");
                //小于   id <5
                QueryBuilder queryBuilder4 = QueryBuilders.rangeQuery("id").lt("5");
                //小于等于 id <=5
                QueryBuilder queryBuilder5 = QueryBuilders.rangeQuery("id").lte("5");

以上就是spring boot整合Elasticsearch的原生方式所有实现方式,这个方式主要是后面的聚合查询的基础。

 

posted @ 2019-01-02 17:28  想去天空的猫  阅读(2221)  评论(0编辑  收藏  举报