一、原生java整合elasticsearch的API地址

https://www.elastic.co/guide/en/elasticsearch/client/java-api/6.2/java-docs.html

二、Spring Data的官网

http://projects.spring.io/spring-data/

Spring Data 是的使命是给各种数据访问提供统一的编程接口,不管是关系型数据库(如MySQL),还是非关系数据库(如Redis),或者类似Elasticsearch这样的索引数据库。从而简化开发人员的代码,提高开发效率。

包含很多不同数据操作的模块:

Spring Data Elasticsearch的页面:https://projects.spring.io/spring-data-elasticsearch/

特征:

  • 支持Spring的基于@Configuration的java配置方式,或者XML配置方式

  • 提供了用于操作ES的便捷工具类ElasticsearchTemplate。包括实现文档到POJO之间的自动智能映射。

  • 利用Spring的数据转换服务实现的功能丰富的对象映射

  • 基于注解的元数据映射方式,而且可扩展以支持更多不同的数据格式

  • 根据持久层接口自动生成对应实现方法,无需人工编写基本操作代码(类似mybatis,根据接口自动得到实现)。当然,也支持人工定制查询

三、SprignBoot整合Spring Data Elasticsearch

(1)创建项目

创建spring boot工程


(2)依赖


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.1.7.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.es</groupId>
  12. <artifactId>es</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>es</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  18. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  19. <java.version>1.8</java.version>
  20. </properties>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-starter-web</artifactId>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter-test</artifactId>
  37. <scope>test</scope>
  38. </dependency>
  39. <dependency>
  40. <groupId>org.springframework.boot</groupId>
  41. <artifactId>spring-boot-starter-test</artifactId>
  42. <scope>test</scope>
  43. </dependency>
  44. </dependencies>
  45. <build>
  46. <plugins>
  47. <plugin>
  48. <groupId>org.springframework.boot</groupId>
  49. <artifactId>spring-boot-maven-plugin</artifactId>
  50. </plugin>
  51. </plugins>
  52. </build>
  53. </project>

(3)创建实体

映射---注解

Spring Data通过注解来声明字段的映射属性,有下面的三个注解:

  • @Document 作用在类,标记实体类为文档对象,一般有两个属性

    <ul><li>
    <p>indexName:对应索引库名称</p>
    </li>
    <li>
    <p>type:对应在索引库中的类型</p>
    </li>
    <li>
    <p>shards:分片数量,默认5</p>
    </li>
    <li>
    <p>replicas:副本数量,默认1</p>
    </li>
    </ul></li>
    <li>
    <p><strong><code>@Id</code></strong> 作用在成员变量,标记一个字段作为id主键</p>
    </li>
    <li>
    <p><strong><code>@Field</code> </strong>作用在成员变量,标记为文档的字段,并指定字段映射属性:</p> <ul><li>
    <p>type:字段类型,是是枚举:FieldType,可以是text、long、short、date、integer、object等</p> <ul><li>
    <p>text:存储数据时候,会自动分词,并生成索引</p>
    </li>
    <li>
    <p>keyword:存储数据时候,不会分词建立索引</p>
    </li>
    <li>
    <p>Numerical:数值类型,分两类</p> <ul><li>
    <p>基本数据类型:long、interger、short、byte、double、float、half_float</p>
    </li>
    <li>
    <p>浮点数的高精度类型:scaled_float</p> <ul><li>
    <p>需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原。</p>
    </li>
    </ul></li>
    </ul></li>
    <li>
    <p>Date:日期类型</p> <ul><li>
    <p>elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省空间。</p>
    </li>
    </ul></li>
    </ul></li>
    <li>
    <p>index:是否索引,布尔类型,默认是true</p>
    </li>
    <li>
    <p>store:是否存储,布尔类型,默认是false</p>
    </li>
    <li>
    <p>analyzer:分词器名称,这里的<code>ik_max_word</code>即使用ik分词器</p>
    </li>
    </ul></li>

  1. package com.es.bean;
  2. import org.springframework.data.annotation.Id;
  3. import org.springframework.data.elasticsearch.annotations.Document;
  4. import org.springframework.data.elasticsearch.annotations.Field;
  5. import org.springframework.data.elasticsearch.annotations.FieldType;
  6. @Document(indexName = "item", type = "docs", shards = 1, replicas = 0)
  7. public class Item {
  8. @Id
  9. private Long id;
  10. @Field(type = FieldType.Text, analyzer = "ik_max_word")
  11. private String title; //标题
  12. @Field(type = FieldType.Keyword)
  13. private String category;// 分类
  14. @Field(type = FieldType.Keyword)
  15. private String brand; // 品牌
  16. @Field(type = FieldType.Double)
  17. private Double price; // 价格
  18. @Field(type = FieldType.Keyword, index = false)
  19. private String images; // 图片地址
  20. public Long getId() {
  21. return id;
  22. }
  23. public void setId(Long id) {
  24. this.id = id;
  25. }
  26. public String getTitle() {
  27. return title;
  28. }
  29. public void setTitle(String title) {
  30. this.title = title;
  31. }
  32. public String getCategory() {
  33. return category;
  34. }
  35. public void setCategory(String category) {
  36. this.category = category;
  37. }
  38. public String getBrand() {
  39. return brand;
  40. }
  41. public void setBrand(String brand) {
  42. this.brand = brand;
  43. }
  44. public Double getPrice() {
  45. return price;
  46. }
  47. public void setPrice(Double price) {
  48. this.price = price;
  49. }
  50. public String getImages() {
  51. return images;
  52. }
  53. public void setImages(String images) {
  54. this.images = images;
  55. }
  56. public Item(Long id, String title, String category, String brand, Double price, String images) {
  57. this.id = id;
  58. this.title = title;
  59. this.category = category;
  60. this.brand = brand;
  61. this.price = price;
  62. this.images = images;
  63. }
  64. public Item() {
  65. }
  66. @Override
  67. public String toString() {
  68. return "Item{" +
  69. "id=" + id +
  70. ", title='" + title + '\'' +
  71. ", category='" + category + '\'' +
  72. ", brand='" + brand + '\'' +
  73. ", price=" + price +
  74. ", images='" + images + '\'' +
  75. '}';
  76. }
  77. }

(4)控制层


  1. package com.es.controller;
  2. import com.es.bean.Item;
  3. import com.es.dao.ItemRepository;
  4. import org.elasticsearch.index.query.QueryBuilders;
  5. import org.elasticsearch.search.aggregations.AggregationBuilders;
  6. import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
  7. import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
  8. import org.elasticsearch.search.sort.SortBuilders;
  9. import org.elasticsearch.search.sort.SortOrder;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.data.domain.Page;
  12. import org.springframework.data.domain.PageRequest;
  13. import org.springframework.data.domain.Sort;
  14. import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
  15. import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
  16. import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
  17. import org.springframework.web.bind.annotation.GetMapping;
  18. import org.springframework.web.bind.annotation.RestController;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. @RestController
  22. public class ItemController {
  23. @Autowired
  24. ItemRepository itemRepository;
  25. @Autowired
  26. ElasticsearchTemplate esTemplate;
  27. /**
  28. * 创建索引
  29. * ElasticsearchTemplate中提供了创建索引的API
  30. */
  31. @GetMapping("/create/indices")
  32. public void createIndices() {
  33. // 创建索引,会根据Item类的@Document注解信息来创建
  34. esTemplate.createIndex(Item.class);
  35. // 配置映射,会根据Item类中的id、Field等字段来自动完成映射
  36. esTemplate.putMapping(Item.class);
  37. }
  38. /**
  39. * 删除索引
  40. */
  41. @GetMapping("/delete/indices")
  42. public void deleteIndices() {
  43. esTemplate.deleteIndex(Item.class);
  44. // 根据索引名字删除
  45. //esTemplate.deleteIndex("item");
  46. }
  47. /**
  48. * 创建单个索引
  49. */
  50. @GetMapping("/add/index")
  51. public void addIndex() {
  52. Item item = new Item(1L, "小米手机7", " 手机", "小米", 3499.00, "http://image.baidu.com/13123.jpg");
  53. itemRepository.save(item);
  54. }
  55. /**
  56. * 批量创建索引
  57. */
  58. @GetMapping("/add/index/list")
  59. public void addIndexList() {
  60. List<Item> list = new ArrayList<Item>();
  61. list.add(new Item(1L, "小米手机7", "手机", "小米", 3299.00, "http://image.baidu.com/13123.jpg"));
  62. list.add(new Item(2L, "坚果手机R1", "手机", "锤子", 3699.00, "http://image.baidu.com/13123.jpg"));
  63. list.add(new Item(3L, "华为META10", "手机", "华为", 4499.00, "http://image.baidu.com/13123.jpg"));
  64. list.add(new Item(4L, "小米Mix2S", "手机", "小米", 4299.00, "http://image.baidu.com/13123.jpg"));
  65. list.add(new Item(5L, "荣耀V10", "手机", "华为", 2799.00, "http://image.baidu.com/13123.jpg"));
  66. // 接收对象集合,实现批量新增
  67. itemRepository.saveAll(list);
  68. }
  69. /**
  70. * 修改索引
  71. */
  72. @GetMapping("/update/index")
  73. public void updateIndex() {
  74. Item item = new Item(1L, "苹果XSMax", "手机", "小米", 3499.00, "http://image.baidu.com/13123.jpg");
  75. itemRepository.save(item);
  76. }
  77. /**
  78. * 查询所有
  79. */
  80. @GetMapping("/find/index")
  81. public Object queryAll() {
  82. // 查找所有
  83. //Iterable<Item> list = this.itemRepository.findAll();
  84. // 对某字段排序查找所有 Sort.by("price").descending() 降序
  85. // Sort.by("price").ascending():升序
  86. Iterable<Item> list = this.itemRepository.findAll(Sort.by("price").ascending());
  87. for (Item item : list) {
  88. System.out.println(item);
  89. }
  90. return list;
  91. }
  92. /**
  93. * 价格范围查询
  94. */
  95. @GetMapping("/find/index/by/price")
  96. public Object queryByPriceBetween() {
  97. List<Item> list = itemRepository.findByPriceBetween(2000.00, 3500.00);
  98. for (Item item : list) {
  99. System.out.println("item = " + item);
  100. }
  101. return list;
  102. }
  103. @GetMapping("/find/index/findByCategoryAndPrice")
  104. public Object findByNameAndPrice() {
  105. List<Item> list = itemRepository.findByCategoryAndPrice("手机", 3699.00);
  106. for (Item item : list) {
  107. System.out.println(item);
  108. }
  109. return list;
  110. }
  111. /**
  112. * match底层是词条匹配
  113. *
  114. * @return
  115. */
  116. @GetMapping("/find/index/matchQuery")
  117. public Object matchQuery() {
  118. //构建查询条件
  119. NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
  120. //添加分词查询
  121. builder.withQuery(QueryBuilders.matchQuery("title", "华为"));
  122. // 查询 自动分页 ,默认查找第一页的10条数据
  123. Page<Item> list = itemRepository.search(builder.build());
  124. //总条数
  125. System.out.println(list.getTotalElements());
  126. for (Item it : list) {
  127. System.out.println(it);
  128. }
  129. return list;
  130. }
  131. /**
  132. * termQuery
  133. *
  134. * @return
  135. */
  136. @GetMapping("/find/index/termQuery")
  137. public Object termQuery() {
  138. // 查询条件生成器
  139. NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  140. queryBuilder.withQuery(QueryBuilders.termQuery("price", 3499.00));
  141. // 查询 自动分页 ,默认查找第一页的10条数据
  142. Page<Item> list = itemRepository.search(queryBuilder.build());
  143. for (Item it : list) {
  144. System.out.println(it);
  145. }
  146. return list;
  147. }
  148. /**
  149. * booleanQuery
  150. *
  151. * @return
  152. */
  153. @GetMapping("/find/index/booleanQuery")
  154. public Object booleanQuery() {
  155. NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  156. queryBuilder.withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("title", "华为")).must(QueryBuilders.matchQuery("brand", "华为")));
  157. //查找
  158. Page<Item> list = itemRepository.search(queryBuilder.build());
  159. System.out.println("总条数:" + list.getTotalElements());
  160. for (Item it : list) {
  161. System.out.println(it);
  162. }
  163. return list;
  164. }
  165. /**
  166. * 模糊查询
  167. *
  168. * @return
  169. */
  170. @GetMapping("/find/index/fuzzyQuery")
  171. public Object fuzzyQuery() {
  172. NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  173. queryBuilder.withQuery(QueryBuilders.fuzzyQuery("title", "faceoooo"));
  174. Page<Item> list = itemRepository.search(queryBuilder.build());
  175. System.out.println("总条数:" + list.getTotalElements());
  176. for (Item it : list) {
  177. System.out.println(it);
  178. }
  179. return list;
  180. }
  181. /**
  182. * 分页查询
  183. *
  184. * @return
  185. */
  186. @GetMapping("/find/index/pageSearch")
  187. public Object pageSearch() {
  188. NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  189. queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
  190. //分页
  191. int page = 0;
  192. int size = 3;
  193. queryBuilder.withPageable(PageRequest.of(page, size));
  194. //搜索
  195. Page<Item> page1 = itemRepository.search(queryBuilder.build());
  196. //总条数
  197. System.out.println("总条数:" + page1.getTotalElements());
  198. //总页数
  199. System.out.println(page1.getTotalPages());
  200. // 当前页
  201. System.out.println(page1.getNumber());
  202. //每页大小
  203. System.out.println(page1.getSize());
  204. //所有数据
  205. for (Item item : page1) {
  206. System.out.println(item);
  207. }
  208. return page1;
  209. }
  210. /**
  211. * 排序查询
  212. */
  213. @GetMapping("/find/index/searchAndSort")
  214. public void searchAndSort() {
  215. // 构建查询条件
  216. NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  217. // 添加基本分词查询
  218. queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));
  219. // 排序
  220. queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
  221. // 搜索,获取结果
  222. Page<Item> items = this.itemRepository.search(queryBuilder.build());
  223. // 总条数
  224. long total = items.getTotalElements();
  225. System.out.println("总条数 = " + total);
  226. for (Item item : items) {
  227. System.out.println(item);
  228. }
  229. }
  230. /**
  231. * 聚合查询
  232. * 聚合为桶bucket--分组--类似group by
  233. * 桶就是分组,比如这里我们按照品牌brand进行分组:
  234. */
  235. @GetMapping("/find/index/searchAgg")
  236. public Object searchAgg(){
  237. NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
  238. // 不查询任何结果
  239. //queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
  240. // 1、添加一个新的聚合,聚合类型为terms,聚合名称为brands,聚合字段为brand
  241. queryBuilder.addAggregation(
  242. AggregationBuilders.terms("brands").field("brand"));
  243. // 2、查询,需要把结果强转为AggregatedPage类型
  244. AggregatedPage<Item> aggPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());
  245. // 3、解析
  246. // 3.1、从结果中取出名为brands的那个聚合,
  247. // 因为是利用String类型字段来进行的term聚合,所以结果要强转为StringTerm类型
  248. StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
  249. // 3.2、获取桶
  250. List<StringTerms.Bucket> buckets = agg.getBuckets();
  251. // 3.3、遍历
  252. for (StringTerms.Bucket bucket : buckets) {
  253. // 3.4、获取桶中的key,即品牌名称
  254. System.out.println(bucket.getKeyAsString());
  255. // 3.5、获取桶中的文档数量
  256. System.out.println(bucket.getDocCount());
  257. }
  258. return buckets;
  259. }
  260. /**
  261. * 嵌套聚合,求平均值---度量
  262. * 需求:求桶--分组,每个品牌手机的平均价格
  263. * 思路:(分组求桶) + 求平均值(度量)
  264. */
  265. @GetMapping("/find/index/subAgg")
  266. public Object subAgg() {
  267. NativeSearchQueryBuilder queryBuilder1 = new NativeSearchQueryBuilder();
  268. queryBuilder1.addAggregation(AggregationBuilders.terms("brands").field("brand")
  269. .subAggregation(AggregationBuilders.avg("priceAvg").field("price")));
  270. AggregatedPage<Item> aggregatedPage = (AggregatedPage<Item>) itemRepository.search(queryBuilder1.build());
  271. StringTerms brands = (StringTerms) aggregatedPage.getAggregation("brands");
  272. List<StringTerms.Bucket> buckets = brands.getBuckets();
  273. for (StringTerms.Bucket bu : buckets) {
  274. System.out.print(bu.getKeyAsString() + "\t" + bu.getDocCount() + "\t");
  275. InternalAvg avg = (InternalAvg) bu.getAggregations().asMap().get("priceAvg");
  276. System.out.println(avg.getValue());
  277. }
  278. return buckets;
  279. }
  280. }

(5)Repository接口


  1. package com.es.dao;
  2. import com.es.bean.Item;
  3. import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
  4. import java.util.List;
  5. /**
  6. * 接口关系:
  7. * ElasticsearchRepository --> ElasticsearchCrudRepository --> PagingAndSortingRepository --> CrudRepository
  8. */
  9. public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
  10. /**
  11. * 根据价格区间查询
  12. * @param price1
  13. * @param price2
  14. * @return
  15. */
  16. List<Item> findByPriceBetween(double price1, double price2);
  17. List<Item> findByCategoryAndPrice(String name, double price);
  18. }

(6)application.properties配置


  1. spring.data.elasticsearch.repositories.enabled=true
  2. spring.data.elasticsearch.cluster-name=zzq-es
  3. spring.data.elasticsearch.cluster-nodes=192.168.1.16:9300

(7)启动类


  1. package com.es;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class EsApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(EsApplication.class, args);
  8. }
  9. }

四、总结

(1)端口问题

redis:   6379
mq:   浏览器访问  6181

         代码访问  61616
es: 浏览器访问  9200

          代码访问  9300

(2)自定义方法

Keyword Sample
And findByNameAndPrice findBy属性名1And属性名2
Or findByNameOrPrice
Is findByName
Not findByNameNot
Between findByPriceBetween
LessThanEqual findByPriceLessThan
GreaterThanEqual findByPriceGreaterThan
Before findByPriceBefore
After findByPriceAfter
Like findByNameLike
StartingWith findByNameStartingWith
Contains/Containing findByNameContaining
In findByNameIn(Collection<String>names)
NotIn findByNameNotIn(Collection<String>names)
Near findByStoreNear
True findByAvailableTrue
False findByAvailableFalse
OrderBy findByAvailableTrueOrderByNameDesc

例如


  1. public interface ItemRepository extends ElasticsearchRepository<Item,Long> {
  2. /**
  3. * 根据价格区间查询
  4. * @param price1
  5. * @param price2
  6. * @return
  7. */
  8. List<Item> findByPriceBetween(double price1, double price2);
  9. }

(3)基本概念

Elasticsearch也是基于Lucene的全文检索库,本质也是存储数据,很多概念与关系型数据相似。

对比关系:

索引库(indices)--------------------------------Databases 数据库


  1. 类型(type)-----------------------------Table 数据表
  2. 文档(Document)----------------Row 行
  3. 字段(Field)-------------------Columns 列
概念 说明
索引库(indices) indices是index的复数,代表许多的索引,
类型(type) 类型是模拟mysql中的table概念,一个索引库下可以有不同类型的索引,比如商品索引,订单索引,其数据格式不同。不过这会导致索引库混乱,因此未来版本中会移除这个概念
文档(document) 存入索引库原始的数据。比如每一条商品信息,就是一个文档
字段(field) 文档中的属性
映射配置(mappings) 字段的数据类型、属性、是否索引、是否存储等特性

另外,在Elasticsearch有一些集群相关的概念:

索引集(Indices,index的复数):逻辑上的完整索引

分片(shard):数据拆分后的各个部分

副本(replica):每个分片的复制

要注意的是:Elasticsearch本身就是分布式的,因此即便你只有一个节点,Elasticsearch默认也会对你的数据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。

github : https://github.com/2014team/elasticsearch

推荐文章:https://blog.csdn.net/weixin_42633131/article/details/82902812

SprignBoot整合Spring Data Elasticsearch的更多相关文章

  1. SpringBoot整合Spring Data Elasticsearch

    Spring Data Elasticsearch提供了ElasticsearchTemplate工具类,实现了POJO与elasticsearch文档之间的映射 elasticsearch本质也是存 ...

  2. 3.4_springboot2.x整合spring Data Elasticsearch

    Spring Data Elasticsearch 是spring data对elasticsearch进行的封装. 这里有两种方式操作elasticsearch: 1.使用Elasticsearch ...

  3. Spring Boot + Spring Data + Elasticsearch实例

    Spring Boot + Spring Data + Elasticsearch实例 学习了:https://blog.csdn.net/huangshulang1234/article/detai ...

  4. elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    一.ES Client 简介 1. ES是一个服务,采用C/S结构 2. 回顾 ES的架构 3. ES支持的客户端连接方式 3.1 REST API ,端口 9200 这种连接方式对应于架构图中的RE ...

  5. Elasticsearch基本用法(2)--Spring Data Elasticsearch

    Spring Data Elasticsearch是Spring Data项目下的一个子模块. 查看 Spring Data的官网:http://projects.spring.io/spring-d ...

  6. Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介.Java REST Client.Java Client.Spri ...

  7. spring data elasticsearch 使用

    很久之前就安装了elasticsearch,一直没用java用过,最近看了一下spring data系列的elasticsearch,这里写一篇心得. 如果尚未安装elasticsearch,可以 参 ...

  8. elasticsearch 拼音+ik分词,spring data elasticsearch 拼音分词

    elasticsearch 自定义分词器 安装拼音分词器.ik分词器 拼音分词器: https://github.com/medcl/elasticsearch-analysis-pinyin/rel ...

  9. How to provide highlighting with Spring data elasticsearch

    How to provide highlighting with Spring data elasticsearch @Test public void shouldReturnHighlighted ...

随机推荐

  1. webpack 打包html文件

    webpack 打包html文件 webpack.config.js配置文件内容为: /** * loader: 1. 下载 2. 使用(配置) * plugins:1. 下载 2. 引入 3.使用 ...

  2. React + 导入模块的一个错误

    导入模块的时候出现这个错误: Attempted import error: 'd3' does not contain a default export (imported as 'd3'). 把导 ...

  3. redux 的简单实用案例

    redux 的简单实用案例 整体思想与结构 创建一个Action 创建一个Reducer 创建Store 在App组件开始使用 整体思想与结构 文件目录如下: 构建 action,通过创建一个函数,然 ...

  4. 9组-Alpha冲刺-3/6

    一.基本情况 队名:不行就摆了吧 组长博客:https://www.cnblogs.com/Microsoft-hc/p/15546622.html 小组人数: 8 二.冲刺概况汇报 卢浩玮 过去两天 ...

  5. js 正则表达式 验证与限制

    .... //验证身份证格式 function onIDCardsValidation(e) { if (e.isValid) { var pattern = /\d*/; if (!(e.value ...

  6. Alpine容器安装运行ssh

    写在前面 本文介绍了在Alpine容器(docker)上安装运行ssh并保证外界(宿主机)能通过ssh登录的方法,给出了相应的命令.在下在探索过程中借鉴了许多前人的经验,在此先行谢过,所有参考内容都会 ...

  7. [atARC128F]Game against Robot

    为了方便,下文中的$n$是原来的$\frac{n}{2}$ 当确定排列$\{p_{i}\}$后,将$a_{i}$按照$p_{i}$从大到小排序,那么机器人即会不断选第一个元素 考虑玩家最后选择的$n$ ...

  8. [hdu7012]Miserable Faith

    类似于[NOI2021]轻重边的逆过程,操作1即为对$u$​执行access(根为1),$dist(u,v)$​即为$u$​到$v$​的虚边数 对前者用LCT维护,并记录轻重边的切换,显然切换总量为$ ...

  9. [atARC116F]Deque Game

    假设两个操作者分别为$A$和$B$,其中$A$希望最大.$B$希望最小 (并不默认$A$为整局游戏的先手,仅是最终的结果考虑$A$为先手时) 记第$i$个队列第$j$个元素为$a_{i,j}$(其中$ ...

  10. [hiho1952]运算数

    可以发现如果将根的结果写成多项式,可以发现只需要预处理出f[i][j]表示以i为根的子树j次项有多少个,g[i]表示从n个数中选取i个数相乘的和,就可以通过\sum_{i=1}^{n}f[1][i]\ ...