ElasticSearch之基于SpringBoot使用SpringData操作ES

7. SpringData操作ES

参考https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.mapping

7.1 创建项目、导入依赖、编写配置文件

一定要注意版本的问题:版本不一致,会带来很多问题:

Spring Data ElasticsearchElasticsearchSpring Boot
3.2.x6.8.42.2.x
3.1.x6.2.22.1.x
3.0.x5.5.02.0.x
2.1.x2.4.01.5.x

首先导入关键dependency

<!--关键依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--lombok插件-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
# cluster-name不要写错
spring.data.elasticsearch.cluster-name=elasticsearch
# Java调用时端口是9300,restfu调用端口是9200,注意区分
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s

7.2 编写实体类型

然后编写实体类型type

/**
 * @author Honyelchak
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
// 若ES中没有指定的索引,会自动创建。
// shards 分片数  replicas 副本数 refreshInterval 刷新间隔
@Document(indexName = "hello_world", type="user", shards = 2, replicas = 3)
public class Item implements Serializable {
    @Id
    private String id;
    private String userName;
    @Field(type = FieldType.Keyword)
    private String passWord;
    @Field(type = FieldType.Integer)
    private Integer age;
    // text 类型的会分词
    @Field(type = FieldType.Text, analyzer = "")
    private String comment;
}
  • @Document(indexName = "hello_world",type = "user",shards = 5,replicas = 1) : 标注在实体类上,声明存储的索引和类型刚才,

    • indexName: 索引名称
    • type:索引类型
    • shards:分片的数量,默认为·5
    • replicas:副本的数量,默认为1
    • refreshInterval: 刷新间隔,默认为1s
    • indexStoreType:索引文件存储类型,默认为fs
  • @Field标注在属性上,用来指定属性的类型。其中的属性如下:

    • analyzer:指定分词器,es中默认使用的标准分词器,比如我们需要指定中文IK分词器,可以指定值为ik_max_word
    • type: 指定该属性在es中的类型,其中的值是FileType类型的值,比如FileType.Text类型对应es中的text类型
    • index:指定该词是否需要索引,默认为true
    • store:指定该属性内容是否存储在ES,默认为false
    • fielddata :指定该属性能否进行排序,因为es中的text类型是不能进行排序(已经分词了)
    • searchAnalyzer : 指定搜索使用的分词器
    • name:字段名称,可以在ES文档中表示,若未设置,则使用Java字段名称。

7.3 使用方法:

  1. 直接在 dao接口继承 ElasticsearchRepository

  2. 直接在 Service/Controller 中引入 ElasticsearchTemplate

7.3.1 继承ElasticsearchRepository
7.3.1.1 SpringData重要接口

img

Spring Data的中央接口是Repository

  • 它需要实体类以及实体类的ID作为类型参数来管理。
  • 该接口主要用作标记接口(内无实现),以捕获要使用的类型并帮助您发现扩展该接口的接口
  • CrudRepository规定对于正在管理的实体类复杂的CRUD功能。
public interface CrudRepository<T, ID> extends Repository<T, ID> {

  <S extends T> S save(S entity);      

  Optional<T> findById(ID primaryKey); 

  Iterable<T> findAll();               

  long count();                        

  void delete(T entity);               

  boolean existsById(ID primaryKey);   

  // … more functionality omitted.
}

ES中的PagingAndSortingRepository接口 继承了CrudRepository。简化了分页操作和排序操作:

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

而在SpringBoot项目中,常用的是ElasticsearchRepository,他在ElasticsearchCrudRepository的基础上补充了一些与查询相关的方法。

7.3.1.2 根据方法名查询
interface BookRepository extends Repository<Book, String> {
  List<Book> findByNameAndPrice(String name, Integer price);
}
7.3.1.3 @Query(json)查询

上面的方法名称将转换为以下Elasticsearch json查询,

{
    "query": {
        "bool" : {
            "must" : [
                { "query_string" : { "query" : "?", "fields" : [ "name" ] } },
                { "query_string" : { "query" : "?", "fields" : [ "price" ] } }
            ]
        }
    }
}

还可以用@Query注解来自定义查询语句,例如:

@Query("{\n" +
       "    \"bool\": {\n" +
       "      \"must\": [\n" +
       "        {\n" +
       "          \"match\": {\n" +
       "            \"userName\": \"?0\"\n" +
       "          }\n" +
       "        }\n" +
       "      ]\n" +
       "    }\n" +
       "  }")
List<User> selectByUserName(String userName);

PS: 其中的?是占位符,0表示第一个参数

对应表:

关键词样品Elasticsearch查询字符串
AndfindByNameAndPrice{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, { "query_string" : { "query" : "?", "fields" : [ "price" ] } } ] } }}
OrfindByNameOrPrice{ "query" : { "bool" : { "should" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, { "query_string" : { "query" : "?", "fields" : [ "price" ] } } ] } }}
IsfindByName{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } } ] } }}
NotfindByNameNot{ "query" : { "bool" : { "must_not" : [ { "query_string" : { "query" : "?", "fields" : [ "name" ] } } ] } }}
BetweenfindByPriceBetween{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}
LessThanfindByPriceLessThan{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } } ] } }}
LessThanEqualfindByPriceLessThanEqual{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}
GreaterThanfindByPriceGreaterThan{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } } ] } }}
GreaterThanEqualfindByPriceGreaterThan{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } ] } }}
BeforefindByPriceBefore{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } ] } }}
AfterfindByPriceAfter{ "query" : { "bool" : { "must" : [ {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } ] } }}
LikefindByNameLike{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
StartingWithfindByNameStartingWith{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
EndingWithfindByNameEndingWith{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
Contains/ContainingfindByNameContaining{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "*?*", "fields" : [ "name" ] }, "analyze_wildcard": true } ] } }}
InfindByNameIn(Collectionnames){ "query" : { "bool" : { "must" : [ {"bool" : {"must" : [ {"terms" : {"name" : ["?","?"]}} ] } } ] } }}
NotInfindByNameNotIn(Collectionnames){ "query" : { "bool" : { "must" : [ {"bool" : {"must_not" : [ {"terms" : {"name" : ["?","?"]}} ] } } ] } }}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "true", "fields" : [ "available" ] } } ] } }}
FalsefindByAvailableFalse{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "false", "fields" : [ "available" ] } } ] } }}
OrderByfindByAvailableTrueOrderByNameDesc{ "query" : { "bool" : { "must" : [ { "query_string" : { "query" : "true", "fields" : [ "available" ] } } ] } }, "sort":[{"name":{"order":"desc"}}] }
7.3.2 引入ElasticsearchTemplate

img

	@Autowired
	private ElasticsearchTemplate elasticsearchTemplate;
	@GetMapping("createIndex")
    public boolean createIndex(String indexName) {
        return elasticsearchTemplate.createIndex(indexName);
    }

    @GetMapping("deleteIndex")
    public boolean deleteIndex(String indexName) {
        return elasticsearchTemplate.deleteIndex(indexName);
    }

    @GetMapping("indexIsExist")
    public boolean indexIsExist(String indexName) {
        return elasticsearchTemplate.indexExists(indexName);
    }

    @GetMapping("typeIsExist")
    public boolean typeIsExist(String indexName, String type) {
        return elasticsearchTemplate.typeExists(indexName, type);
    }

    @GetMapping("getMapping")
    public Map getMapping(String indexName, String type) {
        return elasticsearchTemplate.getMapping(indexName, type);
    }

    @GetMapping("getSetting")
    public Map getSetting(String indexName) {
        return elasticsearchTemplate.getSetting(indexName);
    }

7.4 高级查询

  • QueryBuilders 构建查询关键词
  • SortBuilders 构建对关键字的排序
  • NativeSearchQueryBuilder 对前两个条件进行封装,
  • Repository : 进行查询
// 分词查询 :comment中包含中国的用户,并且以age倒序返回。
@Test
public void searchByCommentSortByAge() {
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.should(QueryBuilders.termQuery("comment", "中国"));
    FieldSortBuilder sortBuilder = SortBuilders.fieldSort("age").order(SortOrder.DESC);

    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
    nativeSearchQueryBuilder.withSort(sortBuilder);

    NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
    Page<Item> itemsPage = itemRepository.search(searchQuery);

    if (itemsPage != null) {
        List<Item> items = itemsPage.getContent();
        items.forEach(System.out::println);
    } else {
        System.out.println("can not find that!");
    }

}
// 查询userName为fanqi的用户,并且以age倒序返回。
@Test
public void searchByUserNameSortByAge() {
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.should(QueryBuilders.termQuery("userName", "fanqi"));
    FieldSortBuilder sortBuilder = SortBuilders.fieldSort("age").order(SortOrder.DESC);

    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
    nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
    nativeSearchQueryBuilder.withSort(sortBuilder);

    NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
    Page<Item> itemsPage = itemRepository.search(searchQuery);

    if (itemsPage != null) {
        List<Item> items = itemsPage.getContent();
        items.forEach(System.out::println);
    } else {
        System.out.println("can not find that!");
    }

}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot使用 Elasticsearch 进行插入操作,您可以按照以下步骤进行: 1. 添加 Elasticsearch 相关依赖:在您的项目的构建文件(如 Maven 的 pom.xml 或 Gradle 的 build.gradle)中,添加适用于 ElasticsearchSpring Boot Starter 依赖。例如,对于 Maven,您可以添加以下依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> ``` 2. 配置 Elasticsearch 连接信息:在您的应用程序配置文件(如 application.properties 或 application.yml)中,添加 Elasticsearch 连接相关的配置信息,包括主机名、端口号、集群名称等。例如: ```properties spring.data.elasticsearch.cluster-nodes=localhost:9200 ``` 3. 创建实体类:创建一个用于映射 Elasticsearch 文档的实体类。该类应使用 `@Document` 注解指定 Elasticsearch 的索引名和类型。例如: ```java import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; @Document(indexName = "my_index", type = "my_type") public class MyEntity { @Id private String id; private String field1; private String field2; // getter and setter methods } ``` 4. 创建 ElasticsearchRepository 接口:创建一个继承自 `ElasticsearchRepository` 的接口,用于对 Elasticsearch 进行增删改查操作。例如: ```java import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; public interface MyEntityRepository extends ElasticsearchRepository<MyEntity, String> { } ``` 5. 使用 ElasticsearchRepository 进行插入操作:在您的代码中,通过自动装配 `MyEntityRepository` 对象,即可使用其中定义的方法进行 Elasticsearch 的插入操作。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyEntityService { @Autowired private MyEntityRepository myEntityRepository; public void saveEntity(MyEntity entity) { myEntityRepository.save(entity); } } ``` 6. 调用插入方法:在您的代码中,创建一个 `MyEntity` 对象,设置相应的字段值,然后调用 `saveEntity` 方法进行插入操作。例如: ```java MyEntity entity = new MyEntity(); entity.setId("1"); entity.setField1("value1"); entity.setField2("value2"); myEntityService.saveEntity(entity); ``` 通过以上步骤,您可以使用 Spring BootElasticsearch 完成插入操作。请根据实际需求进行相应的调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Honyelchak

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值