SpringBoot2.3整合Elasticsearch7.x完整版


微信扫码关注

前言

本文介绍SpringBoot2.3整合Elasticsearch7.x完整版流程

废话不多说,直接开始

准备

1、首先确保安装docker和docker-compose,如还未安装docker以及docker-compose,请阅读 Centos7.X安装docker及docker-compose 来安装,若已经安装,请继续查看以下教程

2、Springboot版本:2.3.3.RELEASE;Elasticsearch版本:7.7.0 ;Kibana:7.7.0;jdk:1.8

安装Elasticsearch及Kibana

本文介绍以docker-compose方式来安装

mkdir -R /wilton/elasticsearch
cd /wilton/elasticsearch

编辑脚本:vim docker-compose.yml

version: '3'
services:
  elasticsearch:
    image: elasticsearch:7.7.0
    container_name: elasticsearch
    environment:
      - "cluster.name=elastic" #设置集群名称为elastic
      - "discovery.type=single-node" #以单一节点模式启动
      - "ES_JAVA_OPTS=-Xms2048m -Xmx4096m" #设置使用jvm内存大小
    volumes:
      - /wilton/elasticsearch/data/plugins:/usr/share/elasticsearch/plugins #插件文件挂载
      - /wilton/elasticsearch/data/data:/usr/share/elasticsearch/data #数据文件挂载
      - /wilton/elasticsearch/data/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml #配置文件挂载
    ports:
      - 9200:9200
      - 9300:9300
  kibana:
    image: kibana:7.7.0
    container_name: kibana
    links:
        - elasticsearch:es #配置elasticsearch域名为es
    depends_on:
      - elasticsearch #kibana在elasticsearch启动之后再启动
    environment:
      - "elasticsearch.hosts=http://127.0.0.1:9200" #设置访问elasticsearch的地址
    volumes:
      - /wilton/kibana/data/config:/usr/share/kibana/config #配置文件挂载
    ports:
      - 5601:5601

elasticsearch.yml配置文件

cluster.name: "docker-master"
network.host: 0.0.0.0

kibana.yml配置文件

server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://127.0.0.1:9200" ]
i18n.locale: "zh-CN"

启动

docker-compose up -d

访问:http://localhost:9200/

image-20201221163913139

访问 kibana:http://localhost:5601/

image-20201221164103712

SpringBoot整合 Spring Data Elasticsearch

Spring Data Elasticsearch是Spring提供的一种以Spring Data风格来操作数据存储的方式,它可以避免编写大量的样板代码。

SpringBoot版本:2.3

  • 添加 pom 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  • 常用注解:

    @Document :标示映射到Elasticsearch文档上的领域对象

    //标示映射到Elasticsearch文档上的领域对象
    public @interface Document {
      //索引库名次,mysql中数据库的概念
        String indexName();
      //文档类型,mysql中表的概念
        String type() default "";
      //默认分片数
        short shards() default 5;
      //默认副本数量
        short replicas() default 1;
    
    }

@Id :表示是文档的id,文档可以认为是mysql中表行的概念

  //表示是文档的id,文档可以认为是mysql中表行的概念
  public @interface Id {
  }

@Filed :文档中字段的类型、是否建立倒排索引、是否进行存储

  public @interface Field {
    //文档中字段的类型
      FieldType type() default FieldType.Auto;
    //是否建立倒排索引
      boolean index() default true;
    //是否进行存储
      boolean store() default false;
    //分词器名次
      String analyzer() default "";
  }
  //为文档自动指定元数据类型
  public enum FieldType {
      Text,//会进行分词并建了索引的字符类型
      Integer,
      Long,
      Date,
      Float,
      Double,
      Boolean,
      Object,
      Auto,//自动判断字段类型
      Nested,//嵌套对象类型
      Ip,
      Attachment,
      Keyword//不会进行分词建立索引的类型
  }

修改application.yml配置文件

修改application.yml文件,在spring节点下添加Elasticsearch相关配置。

spring:
  data:
    elasticsearch:
      repositories:
        enabled: true
    cluster-nodes: 127.0.0.1:9300 # es的连接地址及端口号
    cluster-name: elastic # es集群的名称

实体对象

User.java

package cn.wilton.framework.es.document;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.time.LocalDate;

/**
 * @Description es人员信息
 * @Author: Ranger
 * @Date: 2020/12/21 17:04
 * @Email: wilton.icp@gmail.com
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Document(indexName = "user",type = "docs",shards = 1,replicas = 0)
public class User {
    private static final long serialVersionUID = -1L;
    @Id
    private Long id;

    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
    private String name;

    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String address;

    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
    private String mobile;

    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
    private String email;

    @Field(type = FieldType.Date, format = DateFormat.date)
    private LocalDate birthday;

    @Field(type = FieldType.Keyword)
    private String idCard;

    @Field
    private Company company;
}

Company.java

package cn.wilton.framework.es.document;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

/**
* @Description
* @Author: Ranger
* @Date: 2020/12/22 10:12
* @Email: wilton.icp@gmail.com
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Company {
    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
    private String name;

    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String address;

    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
    private String mobile;

    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
    private String email;

    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String nature;

    @Field(type = FieldType.Text)
    private String website;
}

官方接口:

ElasticsearchRepository<T, ID>

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.data.elasticsearch.repository;

import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.lang.Nullable;

@NoRepositoryBean
public interface ElasticsearchRepository<T, ID> extends PagingAndSortingRepository<T, ID> {
    /** @deprecated */
    @Deprecated
    default <S extends T> S index(S entity) {
        return this.save(entity);
    }

    /** @deprecated */
    @Deprecated
    <S extends T> S indexWithoutRefresh(S var1);

    /** @deprecated */
    Iterable<T> search(QueryBuilder var1);

    /** @deprecated */
    Page<T> search(QueryBuilder var1, Pageable var2);

    /** @deprecated */
    Page<T> search(Query var1);

    Page<T> searchSimilar(T var1, @Nullable String[] var2, Pageable var3);

    /** @deprecated */
    @Deprecated
    void refresh();
}

PagingAndSortingRepository<T, ID>

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.data.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
    Iterable<T> findAll(Sort var1);

    Page<T> findAll(Pageable var1);
}

CrudRepository<T, ID>

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.data.repository;

import java.util.Optional;

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> saveAll(Iterable<S> var1);

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> var1);

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}

自定义Repository

package cn.wilton.framework.es.repository;

import cn.wilton.framework.es.document.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.util.Streamable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @Description
 * @Author: Ranger
 * @Date: 2020/12/22 10:21
 * @Email: wilton.icp@gmail.com
 */
@Repository
public interface OrderRepository extends ElasticsearchRepository<User,Long> {

    /**
     * 根据名字查询数量
     *
     * @param name
     * @return
     */
    long countByName(String name);

    /**
     * 根据地址查询
     *
     * @param address
     * @return
     */
    long countByAddress(String address);

    /**
     * 根据名字删除,并返回删除数量
     *
     * @param name
     * @return
     */
    long deleteByName(String name);

    /**
     * 根据名字删除并返回删除对象
     *
     * @param name
     * @return
     */
    List<User> removeByName(String name);

    /**
     * 根据名字查询
     *
     * @param name
     * @return
     */
    List<User> findByName(String name);

    /**
     * 根据eamil和名字查询
     *
     * @param email
     * @param name
     * @return
     */
    List<User> findByEmailAndName(String email, String name);

    /**
     * 根据email或者手机号查询
     *
     * @param email
     * @param mobile
     * @return
     */
    List<User> findDistinctByEmailOrMobile(String email, String mobile);

    /**
     * 根据名字分页查询
     *
     * @param name
     * @param page
     * @return
     */
    Page<User> findByName(String name, Pageable page);

    /**
     * 根据名字按照id倒序排列查询
     *
     * @param name
     * @param page
     * @return
     */
    Page<User> findByNameOrderByIdDesc(String name, Pageable page);

    /**
     * 根据company对象下的name属性查询
     *
     * @param companyName
     * @param page
     * @return
     */
    Page<User> findByCompanyName(String companyName, Pageable page);

    /**
     * 根据company对象下的name或者根据company对象下的nature属性查询
     *
     * @param companyName
     * @param ompanyNature
     * @return
     */
    List<User> findByCompanyNameOrCompanyNature(String companyName, String ompanyNature);

    /**
     * 根据id范围查询
     *
     * @param start
     * @param end
     * @return
     */
    List<User> findByIdBetween(Long start, Long end);

    /**
     * id小于参数查询
     *
     * @param id
     * @return
     */
    List<User> findByIdLessThan(Long id);

    /**
     * 名字模糊查询并且根据id范围查询
     *
     * @param name
     * @param from
     * @param to
     * @return
     */
    List<User> findByNameLikeAndIdBetween(String name, Long from, Long to);

    /**
     * 忽略email大小写查询
     *
     * @param email
     * @return
     */
    List<User> findByEmailIgnoreCaseLike(String email);

    /**
     * 查询前10
     *
     * @param name
     * @param sort
     * @return
     */
    List<User> findFirst10ByName(String name, Sort sort);

    /**
     * 查询前3
     *
     * @param name
     * @param pageable
     * @return
     */
    Slice<User> findTop3ByName(String name, Pageable pageable);

    /**
     * 根据名字查询前10分页
     *
     * @param name
     * @param pageable
     * @return
     */
    Page<User> queryFirst10ByName(String name, Pageable pageable);

    /**
     * 小于参数id查询
     *
     * @param id
     * @return
     */
    Streamable<User> queryByIdLessThan(Long id);

    /**
     * 大于id参数查询
     *
     * @param id
     * @return
     */
    Streamable<User> queryByIdGreaterThan(Long id);

    /**
     * 根据名字异步查询
     *
     * @param name
     * @return
     */
    @Async
    CompletableFuture<User> findOneByName(String name);

    @Query("{\"range\":{\"id\":{\"from\":\"?0\",\"to\":\"?1\"}}}")
    List<User> queryByIdSql(Long start, Long end);

    @Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}")
    List<User> queryByNameSql(String name);
}

测试接口:

package cn.wilton.framework.es;

import cn.wilton.framework.WiltonElasticsearchApplication;
import cn.wilton.framework.es.document.Company;
import cn.wilton.framework.es.document.User;
import cn.wilton.framework.es.repository.OrderRepository;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.util.Streamable;
import org.springframework.test.context.junit4.SpringRunner;

import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @Description
 * @Author: Ranger
 * @Date: 2020/12/22 11:09
 * @Email: wilton.icp@gmail.com
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WiltonElasticsearchApplication.class)
public class EsTest {

    @Autowired
    private OrderRepository orderRepository;

      @Autowired
    private ElasticsearchRestTemplate esRestTemplate;

    @Test
    public void saveTest() {
        Company c = new Company("百度在线网络技术(北京)有限公司", "北京市海淀区中关村街道", "18510367878", "123@baidu.com", "互联网",
                "https://www.baidu.com");

        User p = new User(1L, "李四", "北京市海淀区中关村街道", "165187413544", "123@baidu.com", LocalDate.of(1999, 2, 12),
                "321302199902121478", c);
        User save = orderRepository.save(p);
        log.info("保存后的结果 {} ", JSONObject.toJSONString(save,true));
    }

    @Test
    public void deleteByIdTest() {
        long id = 0L;
        orderRepository.deleteById(id);
        log.info("删除数据id {}", id);
    }

    @Test
    public void findAllSortTest() {
        // 排序的列
        Sort sort = Sort.by("birthday");
        // 升序
        log.info("升序 {}", JSONObject.toJSONString(orderRepository.findAll(sort),true));
        // sort.descending() 倒序
        log.info("倒序 {}", JSONObject.toJSONString(orderRepository.findAll(sort.descending()),true));
    }

    @Test
    public void countByNameTest() {
        String name = "良";
        long count = orderRepository.countByName(name);
        log.info("姓名:{},数量: {}", name, count);
    }

    @Test
    public void countByAddressTest() {
        String address = "深圳";
        long count = orderRepository.countByAddress(address);
        log.info("地址:{},数量: {}", address, count);
    }

    @Test
    public void deleteByNameTest() {
        String name = "张四";
        long count = orderRepository.deleteByName(name);
        log.info("删除姓名:{},删除数量: {}", name, count);
    }

    @Test
    public void findByNameTest() {
        String name = "李四";
        List<User> list = orderRepository.findByName(name);
        log.info("姓名:{},结果: {}", name, JSONObject.toJSONString(list, true));
    }

    @Test
    public void findByEmailAndNameTest() {
        String name = "阿良";
        String email = "aliang@huawei.com";
        List<User> list = orderRepository.findByEmailAndName(email, name);
        log.info("email:{},name: {},结果: {}", email, name, JSONObject.toJSONString(list, true));
    }

    @Test
    public void findDistinctByEmailOrMobile() {
        String email = "liyiyi@huawei.com";
        String mobile = "16518741234";
        List<User> list = orderRepository.findDistinctByEmailOrMobile(email, mobile);
        log.info("email:{},mobile: {},结果: {}", email, mobile, JSONObject.toJSONString(list, true));
    }

    @Test
    public void findByNamePageTest() {
        // 分页查询
        String name = "李四";
        // 从0开始
        int page = 0;
        // 必须大于0
        int size = 2;

        // 排序可以这样
        // 方式1
//        Sort sort = Sort.by("id");
//        PageRequest.of(page, size, sort);

        // 方式2
        Sort.TypedSort<User> typedSort = Sort.sort(User.class);
        Sort sort = typedSort.by(User::getId).ascending().and(typedSort.by(User::getBirthday).descending());

        Pageable pageable = PageRequest.of(page, size, sort);

        Page<User> result = orderRepository.findByName(name, pageable);
        log.info("name: {}, 分页结果: {}", name, JSONObject.toJSONString(result, true));
    }

    @Test
    public void findByNameNoPageTest() {
        // 不分页
        String name = "李四";
        Pageable unpaged = Pageable.unpaged();
        Page<User> result = orderRepository.findByName(name, unpaged);
        log.info("name: {}, 分页结果: {}", name, JSONObject.toJSONString(result, true));
    }

    @Test
    public void findByNameOrderByIdDescTest() {
        String name = "李四";
        // 从0开始
        int page = 0;
        // 必须大于0
        int size = 2;
        Pageable pageable = PageRequest.of(page, size);
        Page<User> result = orderRepository.findByNameOrderByIdDesc(name, pageable);
        log.info("name: {}, 分页结果: {}", name, JSONObject.toJSONString(result, true));
    }

    @Test
    public void findByCompanyTest() {
        // 从0开始
        int page = 0;
        // 必须大于0
        int size = 2;
        Pageable pageable = PageRequest.of(page, size);
        String companyName = "华为";
        Page<User> result = orderRepository.findByCompanyName(companyName, pageable);
        log.info("分页结果: {}", JSONObject.toJSONString(result, true));
    }

    @Test
    public void findByCompanyNameOrCompanyNatureTest() {
        String companyName = "度";
        String ompanyNature = "硬件";
        List<User> list = orderRepository.findByCompanyNameOrCompanyNature(companyName, ompanyNature);
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void findByIdBetweenTest() {
        long start = 1L;
        long end = 3L;
        List<User> list = orderRepository.findByIdBetween(start, end);
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void findByIdLessThanTest() {
        long id = 3L;
        List<User> list = orderRepository.findByIdLessThan(id);
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void findByIdBetweenAndNameTest() {
        long start = 1L;
        long end = 5L;
        String name = "李";
        List<User> list = orderRepository.findByNameLikeAndIdBetween(name, start, end);
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void findByEmailIgnoreCaseTest() {
        String email = "Huawei";
        List<User> list = orderRepository.findByEmailIgnoreCaseLike(email);
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void streamableTest() {
        // 将结果合并
        Streamable<User> streamable = orderRepository.queryByIdGreaterThan(5L)
                .and(orderRepository.queryByIdLessThan(2L));
        List<User> list = streamable.toList();
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void findOneByNameTest() throws InterruptedException, ExecutionException {
        String name = "李四";
        CompletableFuture<User> future = orderRepository.findOneByName(name);
        User User = future.get();
        log.info("结果: {}", JSONObject.toJSONString(User, true));

    }

    @Test
    public void queryBySqlTest() {
        List<User> list = orderRepository.queryByIdSql(1L, 3L);
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }

    @Test
    public void queryByNameSqlTest() {
        List<User> list = orderRepository.queryByNameSql("李四");
        log.info("结果: {}", JSONObject.toJSONString(list, true));
    }
}

Spring Data Elasticsearch 接口表达式说明

关键字 示例 查询信息
And findByNameAndPrice { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } }, { “query_string” : { “query” : “?”, “fields” : [ “price” ] } } ] } }}
Or findByNameOrPrice { “query” : { “bool” : { “should” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } }, { “query_string” : { “query” : “?”, “fields” : [ “price” ] } } ] } }}
Is findByName { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } } ] } }}
Not findByNameNot { “query” : { “bool” : { “must_not” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] } } ] } }}
Between findByPriceBetween { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
LessThan findByPriceLessThan { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : false } } } ] } }}
LessThanEqual findByPriceLessThanEqual { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
GreaterThan findByPriceGreaterThan { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : false, “include_upper” : true } } } ] } }}
GreaterThanEqual findByPriceGreaterThan { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : true, “include_upper” : true } } } ] } }}
Before findByPriceBefore { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : null, “to” : ?, “include_lower” : true, “include_upper” : true } } } ] } }}
After findByPriceAfter { “query” : { “bool” : { “must” : [ {“range” : {“price” : {“from” : ?, “to” : null, “include_lower” : true, “include_upper” : true } } } ] } }}
Like findByNameLike { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?*”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
StartingWith findByNameStartingWith { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?*”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
EndingWith findByNameEndingWith { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “*?”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
Contains/Containing findByNameContaining { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “?”, “fields” : [ “name” ] }, “analyze_wildcard”: true } ] } }}
In findByNameIn(Collectionnames) { “query” : { “bool” : { “must” : [ {“bool” : {“must” : [ {“terms” : {“name” : [“?”,”?”]}} ] } } ] } }}
NotIn findByNameNotIn(Collectionnames) { “query” : { “bool” : { “must” : [ {“bool” : {“must_not” : [ {“terms” : {“name” : [“?”,”?”]}} ] } } ] } }}
Near findByStoreNear Not Supported Yet !
TRUE findByAvailableTrue { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “true”, “fields” : [ “available” ] } } ] } }}
FALSE findByAvailableFalse { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “false”, “fields” : [ “available” ] } } ] } }}
OrderBy findByAvailableTrueOrderByNameDesc { “query” : { “bool” : { “must” : [ { “query_string” : { “query” : “true”, “fields” : [ “available” ] } } ] } }, “sort”:[{“name”:{“order”:“desc”}}] }

文章作者: Ranger
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ranger !
评论
评论
  目录