0
点赞
收藏
分享

微信扫一扫

SpringData-ESCRUD

增删改

添加


  • 修改​​ArticleService​​ 添加一个方法做添加


SpringData-ESCRUD_SpringData

public void save(Article article){
    article.setId(UUID.randomUUID().toString());
    articleDao.save(article);
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public class EsApplicationTests {

    @Autowired
    private ArticleService articleService;

    @Test
    public void save() {
        Article article = new Article();
        article.setAuthor("BNTang");
        article.setTitle("Java从入门到精通");
        article.setContent("PHP是世界上最好的语言,奥利给");
        article.setRead(500);
        article.setTypes("Java");
        articleService.save(article);
    }
}

修改


  • 当数据存在时是更新,当数据不存在时,是修改
  • 修改​​ArticleService​​ 代码如下:


SpringData-ESCRUD_SpringBoot_02

/**
 * @author BNTang
 **/
@Service
public class ArticleService {
    @Autowired
    private ArticleDao articleDao;

    public void update(Article article) {
        if (StringUtils.isEmpty(article.getId())) {
            throw new RuntimeException("ID不能为空");
        }
        articleDao.save(article);
    }
}


  • 测试类代码如下:


SpringData-ESCRUD_spring_03

/**
 * @author BNTang
 **/
@SpringBootTest
public class EsApplicationTests {

    @Autowired
    private ArticleService articleService;

    @Test
    public void update() {
        Article article = new Article();
        article.setId("7f4eaee6-9cf4-4af0-a02e-ed666077ecd2");
        article.setAuthor("BNTang");
        article.setTitle("PHP是世界上最好的语言");
        article.setContent("学习不可三天打鱼两天晒网,打铁还需自身硬");
        article.setRead(600);
        article.setTypes("PHP");
        articleService.update(article);
    }
}

批量新增


  • 修改​​ArticleService​


SpringData-ESCRUD_spring_04

/**
 * @author BNTang
 **/
@Service
public class ArticleService {
    @Autowired
    private ArticleDao articleDao;

    public void saveBatch(List<Article> articles) {
        articleDao.saveAll(articles);
    }
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public class EsApplicationTests {

    @Autowired
    private ArticleService articleService;

    @Test
    public void saveBatch() {
        Article article = new Article();
        article.setAuthor("BNTang");
        article.setTitle("文档1");
        article.setContent("我是文档1");
        article.setRead(600);
        article.setTypes("PHP");

        Article article2 = new Article();
        article2.setAuthor("BNTang");
        article2.setTitle("文档2");
        article2.setContent("我是文档2");
        article2.setRead(600);
        article2.setTypes("PHP");

        List<Article> list = new ArrayList<>();
        list.add(article);
        list.add(article2);

        articleService.saveBatch(list);
    }
}

删除


  • 根据​​id​​ 删除
  • 修改​​ArticleService​


SpringData-ESCRUD_ElasticSearch_05

/**
 * @author BNTang
 **/
@Service
public class ArticleService {
    @Autowired
    private ArticleDao articleDao;

    public void deleteById(String id) {
        articleDao.deleteById(id);
    }
}


  • 测试类代码如下:


SpringData-ESCRUD_SpringData_06

/**
 * @author BNTang
 **/
@Service
public class ArticleService {
    @Autowired
    private ArticleDao articleDao;

    public void deleteById(String id) {
        articleDao.deleteById(id);
    }
}

查询


  • 根据​​id​​ 查询
  • 修改​​ArticleService​


/**
 * @author BNTang
 **/
@Service
public class ArticleService {
    @Autowired
    private ArticleDao articleDao;

    public Article getById(String id) {
        return articleDao.findById(id).get();
    }
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public class EsApplicationTests {

    @Autowired
    private ArticleService articleService;

    @Test
    public void getById() {
        Article article = articleService.getById("7dwWSXUBaFv6dXD8PRwo");
        System.out.println(article);
    }
}

JPA语法查询

Keyword

Sample

Elasticsearch Query String

​And​

​findByNameAndPrice​

​{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}​

​Or​

​findByNameOrPrice​

​{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}​

​Is​

​findByName​

​{"bool" : {"must" : {"field" : {"name" : "?"}}}}​

​Between​

​findByPriceBetween​

​{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}​

​LessThanEqual​

​findByPriceLessThan​

​{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}​

​GreaterThanEqual​

​findByPriceGreaterThan​

​{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}​

​Before​

​findByPriceBefore​

​{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}​

​After​

​findByPriceAfter​

​{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}​

​Like​

​findByNameLike​

​{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}​

​StartingWith​

​findByNameStartingWith​

​{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}​

​EndingWith​

​findByNameEndingWith​

​{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}​

​Contains/Containing​

​findByNameContaining​

​{"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}​

​In​

​findByNameIn(Collection<String>names)​

​{"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}​

​NotIn​

​findByNameNotIn(Collection<String>names)​

​{"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}​

​Near​

​findByStoreNear​

​Not Supported Yet !​

​True​

​findByAvailableTrue​

​{"bool" : {"must" : {"field" : {"available" : true}}}}​

​False​

​findByAvailableFalse​

​{"bool" : {"must" : {"field" : {"available" : false}}}}​

​OrderBy​

​findByAvailableTrueOrderByNameDesc​

​{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}​


  • 根据​​content​​ 查询
  • 这里如果是需要分词的字段
  • 首先会将传入的参数进行分词
  • 分完词之后,使用这些分词进行查询
  • 然后取交集
  • 其实就是相当于
  • 分词之后多个​​term​​ 取交集
  • 修改​​ArticleDao​



  • Dao层


/**
 * @author BNTang
 **/
public&nbsp;interface&nbsp;ArticleDao&nbsp;extends&nbsp;ElasticsearchRepository&lt;Article,&nbsp;String&gt;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;findByContent(String&nbsp;content);
}


  • Service层
  • 修改​​ArticleService​


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleDao&nbsp;articleDao;
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;List&lt;Article&gt;&nbsp;getByContent(String&nbsp;content)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;articleDao.findByContent(content);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;content()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;list&nbsp;=&nbsp;articleService.getByContent(&quot;干就完了,奥利给&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(list);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 根据 content 查询
  • 这里会将 content 进行分词
  • 根据分词的结果进行查询
  • 取并集
  • 其实就是相当于​​match​
  • 修改​​ArticleDao​



  • Dao层


/**
 * @author BNTang
 **/
public&nbsp;interface&nbsp;ArticleDao&nbsp;extends&nbsp;ElasticsearchRepository&lt;Article,&nbsp;String&gt;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;findByContentLike(String&nbsp;content);
}


  • Service层


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleDao&nbsp;articleDao;
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;List&lt;Article&gt;&nbsp;getByContentLike(String&nbsp;content)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;articleDao.findByContentLike(content);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;contentLike()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;articleList&nbsp;=&nbsp;articleService.getByContentLike(&quot;老铁,奥利给&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(articleList);
&nbsp;&nbsp;&nbsp;&nbsp;}
}

分页查询


  • 分页查询主要涉及到两个类
  • 一个是​​Page​
  • 一个是​​Pageable​
  • 根据 content 和 title 分页查询
  • 修改​​ArticleDao​



  • Dao层


/**
 * @author BNTang
 **/
public&nbsp;interface&nbsp;ArticleDao&nbsp;extends&nbsp;ElasticsearchRepository&lt;Article,&nbsp;String&gt;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;Page&lt;Article&gt;&nbsp;findByContentLikeOrTitleLike(String&nbsp;content,&nbsp;String&nbsp;title,&nbsp;Pageable&nbsp;pageable);
}


  • Service层


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleDao&nbsp;articleDao;

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Page&lt;Article&gt;&nbsp;getByContentOrTitlePage(String&nbsp;content,&nbsp;String&nbsp;title,&nbsp;int&nbsp;page,&nbsp;int&nbsp;size)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pageable&nbsp;pageable&nbsp;=&nbsp;PageRequest.of(page&nbsp;-&nbsp;1,&nbsp;size);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Page&lt;Article&gt;&nbsp;articlePage&nbsp;=&nbsp;articleDao.findByContentLikeOrTitleLike(content,&nbsp;title,&nbsp;pageable);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;articlePage;
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;testPage1()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Page&lt;Article&gt;&nbsp;page&nbsp;=&nbsp;articleService.getByContentOrTitlePage(&quot;奥利给&quot;,&nbsp;&quot;PHP&quot;,&nbsp;1,&nbsp;2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;总条数:&quot;&nbsp;+&nbsp;page.getTotalElements());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;总页数:&quot;&nbsp;+&nbsp;page.getTotalPages());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;本页数据:&quot;&nbsp;+&nbsp;page.getContent());
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 关于ES分页:​


高级查询


  • 虽然基本查询和自定义方法已经很强大了
  • 但是如果是复杂查询(模糊、通配符、词条查询等)就显得力不从心了
  • 此时,我们只能使用原生查询


基本查询


  • 先来看看基本的玩法
  • 修改​​ArticleService​
  • Service层


SpringData-ESCRUD_spring_07

/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ElasticsearchRestTemplate&nbsp;elasticsearchRestTemplate;

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;List&lt;Article&gt;&nbsp;getByContentNative(String&nbsp;content)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MatchQueryBuilder&nbsp;matchQueryBuilder&nbsp;=&nbsp;QueryBuilders.matchQuery(&quot;content&quot;,&nbsp;content);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeSearchQueryBuilder&nbsp;queryBuilder&nbsp;=&nbsp;new&nbsp;NativeSearchQueryBuilder();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryBuilder.withQuery(matchQueryBuilder);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SearchHits&lt;Article&gt;&nbsp;searchHits&nbsp;=&nbsp;elasticsearchRestTemplate.search(queryBuilder.build(),&nbsp;Article.class);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getByContentNative()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;articleList&nbsp;=&nbsp;articleService.getByContentNative(&quot;干就完了,奥利给&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(articleList);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • ​QueryBuilders​​ 提供了大量的静态方法
  • 用于生成各种不同类型的查询对象,例如:词条、模糊、通配符等​​QueryBuilder​​ 对象



  • ​NativeSearchQueryBuilder​​:是 Spring 提供的一个查询条件构建器,帮助构建 JSON 格式的请求体


分页查询


  • 利用​​NativeSearchQueryBuilder​​ 可以很方便的实现分页:
  • 在​​top.it6666.dao​​​ 中创建一个​​Page​​ 类,代码如下:


/**
 * @author BNTang
 **/
@Data
@NoArgsConstructor
public&nbsp;class&nbsp;Page&lt;T&gt;&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Long&nbsp;totalCount;

&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Integer&nbsp;totalPage;

&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;List&lt;T&gt;&nbsp;list;
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Page(Long&nbsp;totalCount,&nbsp;List&lt;T&gt;&nbsp;list)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.totalCount&nbsp;=&nbsp;totalCount;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.list&nbsp;=&nbsp;list;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Page(Long&nbsp;totalCount,&nbsp;Integer&nbsp;size,&nbsp;List&lt;T&gt;&nbsp;list)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.totalCount&nbsp;=&nbsp;totalCount;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.list&nbsp;=&nbsp;list;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 计算总页数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.totalPage&nbsp;=&nbsp;(int)&nbsp;Math.ceil(totalCount&nbsp;*&nbsp;1.0&nbsp;/&nbsp;size);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 修改​​ArticleService​
  • Service层


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ElasticsearchRestTemplate&nbsp;elasticsearchRestTemplate;

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Page&lt;Article&gt;&nbsp;getPageByContentNative(String&nbsp;content,&nbsp;String&nbsp;title,&nbsp;int&nbsp;page,&nbsp;int&nbsp;size)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeSearchQueryBuilder&nbsp;queryBuilder&nbsp;=&nbsp;new&nbsp;NativeSearchQueryBuilder();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 构造queryBuilder
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BoolQueryBuilder&nbsp;boolQueryBuilder&nbsp;=&nbsp;QueryBuilders.boolQuery();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolQueryBuilder.should(QueryBuilders.matchQuery(&quot;content&quot;,&nbsp;content));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolQueryBuilder.should(QueryBuilders.matchQuery(&quot;title&quot;,&nbsp;title));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryBuilder.withQuery(boolQueryBuilder);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryBuilder.withPageable(PageRequest.of(page&nbsp;-&nbsp;1,&nbsp;size));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SearchHits&lt;Article&gt;&nbsp;searchHits&nbsp;=&nbsp;elasticsearchRestTemplate.search(queryBuilder.build(),&nbsp;Article.class);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 获取查询的数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;articleList&nbsp;=&nbsp;searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 获取总条数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;totalHits&nbsp;=&nbsp;searchHits.getTotalHits();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;Page&lt;Article&gt;(totalHits,&nbsp;size,&nbsp;articleList);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getPageByContentNative()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Page&lt;Article&gt;&nbsp;page&nbsp;=&nbsp;articleService.getPageByContentNative(&quot;奥利给,Java,PHP,文档&quot;,&nbsp;&quot;奥利给,Java,PHP,文档&quot;,&nbsp;1,&nbsp;2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;总条数:&quot;&nbsp;+&nbsp;page.getTotalCount());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;总页数:&quot;&nbsp;+&nbsp;page.getTotalPage());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;本页数据:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;page.getList().forEach(System.out::println);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 可以发现,Elasticsearch 中的分页是从第 0 页开始


排序查询


  • 排序也能通过​​NativeSearchQueryBuilder​​ 来完成:
  • 修改​​ArticleService​
  • Service层


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ElasticsearchRestTemplate&nbsp;elasticsearchRestTemplate;

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Page&lt;Article&gt;&nbsp;getPageByContentNativeSort(String&nbsp;content,&nbsp;String&nbsp;title,&nbsp;int&nbsp;page,&nbsp;int&nbsp;size)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeSearchQueryBuilder&nbsp;queryBuilder&nbsp;=&nbsp;new&nbsp;NativeSearchQueryBuilder();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 构造queryBuilder
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BoolQueryBuilder&nbsp;boolQueryBuilder&nbsp;=&nbsp;QueryBuilders.boolQuery();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolQueryBuilder.should(QueryBuilders.matchQuery(&quot;content&quot;,&nbsp;content));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolQueryBuilder.should(QueryBuilders.matchQuery(&quot;title&quot;,&nbsp;title));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryBuilder.withQuery(boolQueryBuilder);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryBuilder.withPageable(PageRequest.of(page&nbsp;-&nbsp;1,&nbsp;size));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 构造排序对象
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryBuilder.withSort(SortBuilders.fieldSort(&quot;read&quot;).order(SortOrder.DESC));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SearchHits&lt;Article&gt;&nbsp;searchHits&nbsp;=&nbsp;elasticsearchRestTemplate.search(queryBuilder.build(),&nbsp;Article.class);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 获取查询的数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Article&gt;&nbsp;articleList&nbsp;=&nbsp;searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 获取总条数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;totalHits&nbsp;=&nbsp;searchHits.getTotalHits();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;Page&lt;Article&gt;(totalHits,&nbsp;size,&nbsp;articleList);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试类代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getPageByContentNativeSort()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Page&lt;Article&gt;&nbsp;page&nbsp;=&nbsp;articleService.getPageByContentNativeSort(&quot;奥利给,Java,PHP,文档&quot;,&nbsp;&quot;奥利给,Java,PHP,文档&quot;,&nbsp;1,&nbsp;2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;总条数:&quot;&nbsp;+&nbsp;page.getTotalCount());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;总页数:&quot;&nbsp;+&nbsp;page.getTotalPage());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(&quot;本页数据:&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;page.getList().forEach(System.out::println);
&nbsp;&nbsp;&nbsp;&nbsp;}
}

聚合查询


  • 聚合为桶
  • 桶就是分组,比如这里我们按照帖子分类进行分组:



  • Service层,修改​​ArticleService​


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ElasticsearchRestTemplate&nbsp;elasticsearchRestTemplate;

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getCountByTypes()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeSearchQueryBuilder&nbsp;nativeSearchQueryBuilder&nbsp;=&nbsp;new&nbsp;NativeSearchQueryBuilder();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置要查询的字段
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeSearchQueryBuilder.withSourceFilter(new&nbsp;FetchSourceFilter(new&nbsp;String[]{&quot;&quot;},&nbsp;null));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置一下查询的条数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeSearchQueryBuilder.withPageable(PageRequest.of(0,&nbsp;1));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置聚合字段,指定聚合后的字段名,以及根据哪个字段聚合
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(&quot;typeCount&quot;).field(&quot;types&quot;));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 搜索
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SearchHits&lt;Article&gt;&nbsp;searchHits&nbsp;=&nbsp;elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(),&nbsp;Article.class);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 取出来聚合的数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Aggregations&nbsp;aggregations&nbsp;=&nbsp;searchHits.getAggregations();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 取出我们聚合的字段
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Terms&nbsp;terms&nbsp;=&nbsp;aggregations.get(&quot;typeCount&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;?&nbsp;extends&nbsp;Terms.Bucket&gt;&nbsp;buckets&nbsp;=&nbsp;terms.getBuckets();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Terms.Bucket&nbsp;bucket&nbsp;:&nbsp;buckets)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bucket.getKey());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bucket.getDocCount());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getCountByType()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;articleService.getCountByTypes();
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • ????嵌套聚合



  • Service层,修改​​ArticleService​


/**
 * @author BNTang
 **/
@Service
public&nbsp;class&nbsp;ArticleService&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ElasticsearchRestTemplate&nbsp;elasticsearchRestTemplate;

&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getCountAndSum()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NativeSearchQueryBuilder&nbsp;nativeSearchQueryBuilder&nbsp;=&nbsp;new&nbsp;NativeSearchQueryBuilder();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置要查询的字段
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeSearchQueryBuilder.withSourceFilter(new&nbsp;FetchSourceFilter(new&nbsp;String[]{&quot;&quot;},&nbsp;null));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置一下查询的条数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeSearchQueryBuilder.withPageable(PageRequest.of(0,&nbsp;1));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置聚合字段,指定聚合后的字段名,以及根据哪个字段聚合
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nativeSearchQueryBuilder.addAggregation(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 按照types聚合,求总数
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AggregationBuilders.terms(&quot;typeCount&quot;).field(&quot;types&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// types聚合完毕后,再根据read聚合
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.subAggregation(AggregationBuilders.sum(&quot;readNum&quot;).field(&quot;read&quot;))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 搜索
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SearchHits&lt;Article&gt;&nbsp;searchHits&nbsp;=&nbsp;elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(),&nbsp;Article.class);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Aggregations&nbsp;aggregations&nbsp;=&nbsp;searchHits.getAggregations();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Terms&nbsp;terms&nbsp;=&nbsp;aggregations.get(&quot;typeCount&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;?&nbsp;extends&nbsp;Terms.Bucket&gt;&nbsp;buckets&nbsp;=&nbsp;terms.getBuckets();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Terms.Bucket&nbsp;bucket&nbsp;:&nbsp;buckets)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bucket.getKey());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bucket.getDocCount());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Aggregations&nbsp;subAggs&nbsp;=&nbsp;bucket.getAggregations();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sum&nbsp;sum&nbsp;=&nbsp;subAggs.get(&quot;readNum&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(sum.getValue());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}


  • 测试代码如下:


/**
 * @author BNTang
 **/
@SpringBootTest
public&nbsp;class&nbsp;EsApplicationTests&nbsp;{

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArticleService&nbsp;articleService;

&nbsp;&nbsp;&nbsp;&nbsp;@Test
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getCountAndSum()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;articleService.getCountAndSum();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

举报

相关推荐

0 条评论