SpringData操作Elasticsearch

SpringData自定义查询

SpringData框架提供的基本增删改查方法并不能完全满足我们的业务需要

如果是针对当前Es数据,进行个性化的自定义查询,那还是需要自己编写查询代码

就像我们要实现根据关键词查询商品信息一样,完成类似数据库中的模糊查询.

单条件查询

我们使用SpringDataES进行查询,本质上还是相当于ES文档中执行的查询语句

在SpringData框架下,ItemRepository接口中实现更加简单

// SpringData自定义查询
// 我们要编写一个遵循SpringData给定的方法名的格式
// SpringData能够根据我们编写的方法名,推断出查询意图,自动生成能够完成这个查询的语句完成功能
// query(查询):表达当前方法是一个查询方法,类似数据库sql语句的select
// Item/Items:是要查询的实体类的名称,返回集合的查询应该以s结尾
// By(通过/根据):标识开始设置查询条件的关键字,等价于sql语句中的where
// Title:要查询的字段,可以是Item实体类中的任何字段
// Matches(匹配):指定查询的操作条件,Matches是查询匹配关键词的行(document),类似于sql中的like

Iterable queryItemsByTitleMatches(String title);

下面可以开始在测试类中进行测试查询

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

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

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

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

多条件查询 

在相对复杂的查询逻辑下

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

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

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

// 多条件自定义查询
// 多个条件之间要使用and或or进行分隔,表示多个条件之间的逻辑关系
// 我们使用title和brand字段进行多条件查询
// 参数的数量要匹配查询字段的数量
// 声明参数的顺序就是赋值的依据,第一个参数会赋值给第一个条件,和参数名称无关

Iterable queryItemsByTitleMatchesAndBrandMatches(String title,String brand);

 测试代码如下

// 多条件自定义查询
@Test
void queryTwo(){
    // 查询title字段是"游戏",并且品牌是"罗技"的数据
    Iterable 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

排序查询

默认情况下从ES中查询获得的数据排序依据是ES查询得出的相关性分数(score)

但是如果想改变这个排序就需要在查询方法上添加新的关键字

在ItemRepository接口添加具备排序功能的查询方法测试代码如下

// 排序查询
Iterable queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
    											String title,String brand);

测试代码如下 

// 排序查询
@Test
void queryOrder(){
    // 查询title字段是"游戏",或品牌是"罗技"的数据,用价格降序排序显示
    Iterable 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"}]
}

 分页查询

SpringData框架支持完成分页查询

需要在ItemRepository接口中修改方法的参数和返回值就可以实现

//分页查询

//要执行分页查询, 需要返回值类型修改为Page

//这个类型对象支持保存所有查询结果的同时,保存分页信息,例如每页条数、当前页、总页数、总条数等

//参数方面,要有现有所有参数最后一个Pageable类型的参数

//这个参数会在方法被调用时,确定分页查询的页码和每页条数

Page queryItemByTitleMathesOrBrandMatchesOrderByPriceDesc(String title,String brand,Pageable pageable) ;  

测试代码

// 分页查询
@Test
void queryPage(){
    int page=1;          // 要查询的页码
    int pageSize=2;      // 设置每页的条数

    Page pageItems=itemRepository
            .queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
                    "游戏","罗技", PageRequest.of(page-1,pageSize));
    pageItems.forEach(item -> System.out.println(item));

    // pageItems对象包含的分页信息输出如下
    System.out.println("总页数:"+pageItems.getTotalPages());
    System.out.println("总条数:"+pageItems.getTotalElements());
    System.out.println("当前页:"+(pageItems.getNumber()+1));
    System.out.println("每页条数:"+pageItems.getSize());
    System.out.println("是否是首页:"+pageItems.isFirst());
    System.out.println("是否是末页:"+pageItems.isLast());


}

 

你可能感兴趣的:(elasticsearch,大数据,搜索引擎)