Spring Data Elasticsearch(6版本之前)

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

常用注解(用于实体上)

@Document

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

@Id

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

@Field

public @interface Field{
//文档中字段的类型
FieldType type() default FieldType.Auto;
//是否建立倒排索引
boolean index() default true;
//是否进行存储
boolean store() default false;
//分词器名次
String analyzer() default "";
}

FieldType 

//为文档自动指定元数据类型
public enum FieldType {
Text,
//会进行分词并建了索引的字符类型
Integer,
Long,
Date,
Float,
Double,
Boolean,
Object,
Auto,
//自动判断字段类型
Nested,
//嵌套对象类型
Ip,
Attachment,
Keyword
//不会进行分词建立索引的类型
}

整合spring boot

1.pom文件

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2.application.yml

spring:
data:
elasticsearch:
repositories:
enabled: true
cluster-name: elasticsearch
cluster-nodes: 192.168.49.14:9300

3.config文件

否则会报错  java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]

@Configuration
public class ElasticSearchConfig {
/**
* 防止netty的bug
* java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]
*/
@PostConstruct
void init() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
}

4.entity

@Document(indexName = "product", type = "product", shards = 1, replicas = 0)
public class Product {
@Id
private Long id;

/**
* 标题
*/
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;

/**
* 分类
*/
@Field(type = FieldType.Keyword)
private String category;

/**
* 价格
*/
@Field(type = FieldType.Double)
private Double price;

/**
* 图片地址
*/
@Field(index = false, type = FieldType.Keyword)
private String images;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getCategory() {
return category;
}

public void setCategory(String category) {
this.category = category;
}

public Double getPrice() {
return price;
}

public void setPrice(Double price) {
this.price = price;
}

public String getImages() {
return images;
}

public void setImages(String images) {
this.images = images;
}

}

6.继承ElasticsearchRepository

这就是以上说的Sping Data方式的数据操作

@Service
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {

}

继承ElasticsearchRepository接口可以获得常用的数据操作方法

五分钟带你玩转Elasticsearch(十一)小试牛刀——集成spring boot测试环境_mysql

7.controller

@RestController
public class ProductController {

@Autowired
private ProductRepository productRepository;

/**
* 插入
*/
@RequestMapping("/importProduct")
public void importProduct() {
List<Product> list = new ArrayList<Product>();
// 产品1
Product product1 = new Product();
product1.setId(Long.valueOf(1));
product1.setTitle("Haier/海尔 BCD-470WDPG十字对开门风冷变频一级节能家用官方冰箱");
product1.setPrice(3699.00);
product1.setCategory("冰箱");
product1.setImages("http://image.baidu.com/13123.jpg");

// 产品2
Product product2 = new Product();
product2.setId(Long.valueOf(2));
product2.setTitle("Panasonic/松下 NR-TC28WS1-N 风冷无霜家用抑菌三门小体积冰箱");
product2.setPrice(5000.00);
product2.setCategory("冰箱");
product2.setImages("http://image.baidu.com/13123.jpg");

// 产品3
Product product3 = new Product();
product3.setId(Long.valueOf(3));
product3.setTitle("Changhong/长虹 50D4P 50英寸超薄无边全面屏4K超高清智能电视机");
product3.setPrice(2666.00);
product3.setCategory("电视");
product3.setImages("http://image.baidu.com/13123.jpg");

// 产品4
Product product4 = new Product();
product4.setId(Long.valueOf(4));
product4.setTitle("创维40X6 40英寸高清电视机智能网络wifi平板液晶屏家用彩电32 43");
product4.setPrice(1235.00);
product4.setCategory("电视");
product4.setImages("http://image.baidu.com/13123.jpg");

list.add(product1);
list.add(product2);
list.add(product3);
list.add(product4);
productRepository.saveAll(list);
}

/**
* 查询所有 通过自带方法
*
* @return
*/
@RequestMapping("/selectProductAll")
public void selectProductAll() {
Iterable<Product> list = productRepository.findAll();
productRepository.deleteById(Long.valueOf(1));
for (Product product : list) {
System.out.println(product.getTitle());
}
}

/**
* 通过id删除
*/
@RequestMapping("/deleteProduct")
public void deleteProduct() {
productRepository.deleteById(Long.valueOf(1));
}

/**
* 删除全部
*/
@RequestMapping("/deleteProductAll")
public void deleteProductAll() {
productRepository.deleteAll();
}


}

调用以上接口 使用语句在kibana中验证

自定义方法

自定义方法的前提是我们需要继承ElasticsearchRepository接口,利用强大的Spring Data来实现。比如:你的方法名叫做:findByTitle,那么它就知道你是根据title查询,然后自动帮你完成,无需写实现类。

自定义方法命名约定

关键字

使用示例

等同于的ES查询

And

findByNameAndPrice

{“bool” : {“must” : [ {“field” : {“name” : “?”}}, {“field” : {“price” : “?”}} ]}}

Or

findByNameOrPrice

{“bool” : {“should” : [ {“field” : {“name” : “?”}}, {“field” : {“price” : “?”}} ]}}

Is

findByName

{“bool” : {“must” : {“field” : {“name” : “?”}}}}

Not

findByNameNot

{“bool” : {“must_not” : {“field” : {“name” : “?”}}}}

Between

findByPriceBetween

{“bool” : {“must” : {“range” : {“price” : {“from” : ?,”to” : ?,”include_lower” : true,”include_upper” : true}}}}}

LessThanEqual

findByPriceLessThan

{“bool” : {“must” : {“range” : {“price” : {“from” : null,”to” : ?,”include_lower” : true,”include_upper” : true}}}}}

GreaterThanEqual

findByPriceGreaterThan

{“bool” : {“must” : {“range” : {“price” : {“from” : ?,”to” : null,”include_lower” : true,”include_upper” : true}}}}}

Before

findByPriceBefore

{“bool” : {“must” : {“range” : {“price” : {“from” : null,”to” : ?,”include_lower” : true,”include_upper” : true}}}}}

After

findByPriceAfter

{“bool” : {“must” : {“range” : {“price” : {“from” : ?,”to” : null,”include_lower” : true,”include_upper” : true}}}}}

Like

findByNameLike

{“bool” : {“must” : {“field” : {“name” : {“query” : “? *”,”analyze_wildcard” : true}}}}}

StartingWith

findByNameStartingWith

{“bool” : {“must” : {“field” : {“name” : {“query” : “? *”,”analyze_wildcard” : true}}}}}

EndingWith

findByNameEndingWith

{“bool” : {“must” : {“field” : {“name” : {“query” : “*?”,”analyze_wildcard” : true}}}}}

Contains/Containing

findByNameContaining

{“bool” : {“must” : {“field” : {“name” : {“query” : “?”,”analyze_wildcard” : true}}}}}

In

findByNameIn(Collectionnames)

{“bool” : {“must” : {“bool” : {“should” : [ {“field” : {“name” : “?”}}, {“field” : {“name” : “?”}} ]}}}}

NotIn

findByNameNotIn(Collectionnames)

{“bool” : {“must_not” : {“bool” : {“should” : {“field” : {“name” : “?”}}}}}}

True

findByAvailableTrue

{“bool” : {“must” : {“field” : {“available” : true}}}}

False

findByAvailableFalse

{“bool” : {“must” : {“field” : {“available” : false}}}}

OrderBy

findByAvailableTrueOrderByNameDesc

{“sort” : [{ “name” : {“order” : “desc”} }],”bool” : {“must” : {“field” : {“available” : true}}}}

修改ProductRepository

@Service
public interface ProductRepository extends ElasticsearchRepository<Product, Long> {

List<Product> findByTitle(String title);
}

controller

@GetMapping("/selectProductByCustom")
public List<Product> selectProductByCustom(String title) {
List<Product> result = productRepository.findByTitle(title );
return result;
}

即可定制自己的查询

注意:

None of the configured nodes are available: [{#transport#-1}{T9wtimn9R7u6v8SZAmOMsA}{192.168.49.14}{192.168.49.14:9200}]

1:解决:需要开通9300端口

2:楼主这使用的ElasticSearch版本为7.6.0 对应的spring boot版本2.2.5.RELEASE 之前用的2.1.8不好使