Java Spring Cloud X 之 Elasticsearch III

Java Spring Cloud X 之 Elasticsearch III

Elasticsearch

1. SpringData自定义查询

SpringData框架提供基本增删改查方法

但是如果有具体的针对性的查询逻辑,一定还是需要我们自己编写代码

例如实现类似数据库中的模糊查询

2. 单条件查询

我们的查询需求是查询title属性中包含"游戏"这个分词的商品信息

参考模糊查询代码

select * from item where title like '%游戏%'

我们使用ES查询,本质上运行的就是我们在es.http文档中编写的查询语句

但是SpringData框架下,编写查询语句更加简单

我们在ItemRepository接口中添加如下代码

// SpringData自定义查询
// 遵循SpringData框架规定的格式的前提下,编写方法名会自动生成查询逻辑
// query: 表示当前方法是一个查询功能,类似sql中的select
// Item\Items: 表示查询结果的实体类,带s的返回集合
// By:标识开始设置条件,类似sql的where
// Title: 要查询的字段名称
// Matches: 是要执行的查询操作,这里是分词查询,类似sql的like
Iterable<Item> queryItemsByTitleMatches(String title);

再测试类中进行测试

//单条件自定义查询
@Test
void queryOne(){
   // 查询 ES中title字段包含"游戏"分词的数据
   Iterable<Item> items=itemRepository.queryItemsByTitleMatches("游戏");
   items.forEach(item -> System.out.println(item));
}

上面代码运行时底层运行的查询语句为:

### 单条件搜索
POST http://localhost:9200/items/_search
Content-Type: application/json

{
  "query": {"match": { "title":  "游戏" }}
}

3. 多条件查询

在相对复杂的查询逻辑下

经常使用多个条件来定位查询需要的数据

这样就需要逻辑运算符"and"/“or”

ItemRepository接口中添加多条件的查询方法

// 多条件查询
// 两个或多个条件之间直接编写And或Or表示查询逻辑
// 参数名称实际上没有要求必须和字段名称匹配,底层代码是按照参数顺序赋值的
Iterable<Item> queryItemsByTitleMatchesAndBrandMatches(String title,String brand);

上面的查询添加了品牌作为条件

逻辑关系是and(与)

测试代码如下

// 多条件自定义查询
@Test
void queryTwo(){
   Iterable<Item> items=itemRepository
         .queryItemsByTitleMatchesAndBrandMatches("游戏","雷蛇");
   items.forEach(item -> System.out.println(item));
}

底层运行的请求

### 多字段搜索
POST http://localhost:9200/items/_search
Content-Type: application/json

{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "游戏"}},
        { "match": { "brand": "雷蛇"}}
      ]
    }
  }
}

当查询条件关系为And时,查询语句关键字为must

当查询条件关系为Or时,查询语句关键字为should

4.排序查询

上次课我们完成了单条件查询和多条件查询

但是条件的变化只是查询的需求之一

我们还需要像排序等需求的查询

如果实施排序需求,就在Repository接口中添加方法如下

// 排序查询
// 默认情况下,ES查询结果按score排序,如果想按其他的规则排序可以加OrderBy
// 和数据库一样,默认升序排序 Desc结尾会降序
Iterable<Item> queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
                                String title, String brand);

测试代码如下

// 排序查询
@Test
void queryOrder(){
   Iterable<Item> items=itemRepository
      .queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc("游戏","罗技");
   items.forEach(item -> System.out.println(item));
}

底层代码逻辑

### 多字段搜索
POST http://localhost:9200/items/_search
Content-Type: application/json

{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": "游戏"}},
        { "match": { "brand": "罗技"}}
      ]
    }
  },"sort":[{"price":"desc"}]
}

5.分页查询

SpringData框架支持分页查询

只需要修改参数和返回值就能实现自动分页的效果

修改ItemRepository接口代码如下

// 分页查询
// 当查询数据较多时,我们可以利用SpringData的分页功能,按用户要求的页码查询需要的数据
// 返回值修改为Page类型,这个类型对象除了包含Iterable能够包含的集合信息之外,还包含分页信息
Page<Item> queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
        String title, String brand, Pageable pageable);

测试代码如下

// 分页查询
@Test
void queryPage(){
   int pageNum=1;  //页码
   int pageSize=2; //每页条数
   Page<Item> page= itemRepository
      .queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
            "游戏","罗技", PageRequest.of(pageNum-1,pageSize));
   page.forEach(item -> System.out.println(item));
   // page对象中还包含了一些基本的分页信息
   System.out.println("总页数:"+page.getTotalPages());
   System.out.println("当前页:"+page.getNumber());
   System.out.println("每页条数:"+page.getSize());
   System.out.println("当前页是不是首页:"+page.isFirst());
   System.out.println("当前页是不是末页:"+page.isLast());
}

我是将军;我一直都在,。!

你可能感兴趣的:(Java,Spring系列,spring,java,elasticsearch)