ElasticSearch复习
深度解读
-
日志采集方案:Eilebeat(日志采集工具)+ Logstash(数据处理引擎)+ Elasticsearch(数据存储、全文检索、分布式搜索)+ Kibana(展示数据、绘图、搜索)
-
Elasticsearch三大功能:搜索、分析、存储数据
- 概念对应:Elasticsearch — MySQL、Index(索引)— Database(数据库)、Type(类型,废弃)— Table(表)、Document(文档)— Row(行)、Fields(字段)— Column(列)
- 倒排索引:根据关键字找索引
id content --------------------- 1001 my name is lee 1002 my name is leo keyword id --------------------- name 1001,1002 lee 1001
-
基础命令
127.0.0.1:9200/shopping //通过put请求创建shopping索引;通过get请求获取shopping索引;通过Delete请求删除shopping索引 127.0.0.1:9200/_cat/indices?v // 通过get请求获取所有索引
需要注意:
put
请求具有==幂等性==内容不可以重复,而post
不具有幂等性127.0.0.1:9200/shopping/_doc //通过post请求在shopping中添加文档,在body中添加数据,id随机生成 127.0.0.1:9200/shopping/_doc/1001 // post和put请求,指定生成文档id;get请求,根据文档id查询;put,更新文档,在body中传入所有内容;delete,删除 127.0.0.1:9200/shopping/_search { "query":{ "match":{ // "match_all" 全查询 "category":"小米" } } } //get,查询当前索引下的所有文档;get,body中写查询条件 127.0.0.1:9200/shopping/_update/1001 { "doc":{ "修改字段":"修改值" } } // post,在body中传入指定更新内容 127.0.0.1:9200/shopping/_search/q=category:小米 //get,条件查询文档 127.0.0.1:9200/shopping/_search { "query":{ "match_all":{ }, "from":0, "size":2, "_source":["title"], // 指定查询内容 "sort":{ // 排序 "price":{ "order":"desc" } } } } // get,分页查询
127.0.0.1:9200/shopping/_search { "query":{ // 查询 "bool":{ // 条件 "must":[ // 多个条件必须同时成立,"should",满足一个就行 { "match":{ "category":"小米" } }, { "match":{ "price":"1999.00" } } ], "filter":{ // 筛选 "range":{ //范围 "price":{ "gt":9000 //大于 } } } } } } //get,多条件组合查询
常用注解
//标示映射到ElasticSearch文档上的领域对象
public @interface Document{
//索引库名,类似mysql数据库名
String indexName();
//文档类型,类似表
String type() default "";
//默认分片数
short shards() default 5;
//默认副本数量
short replicas() default 1;
}
@Document //文件相关,表示该类的对象可以映射到 Elasticsearch 中的一个文档。
@Id //主键标识
@Field //用于定义实体类属性与 Elasticsearch 文档字段之间的映射关系
@FieldType //用于设置 @Field 注解中的字段类型,@FieldType 注解用于设置这些类型,例如 Text、Keyword、Date、Long、Integer 等。
/*
关键字类型:关键字类型的字段不会被分词,它会被当作一个整体进行索引和查询。这意味着,如果一个字段被定义为关键字类型,那么它的内容不会被拆分成词项,整个内容将作为一个独立的索引项存储。
文本类型:文本类型的字段会被分词,它会被拆分成一个个词项,并将这些词项作为索引项进行存储和查询。这使得文本类型的字段支持全文搜索和模糊匹配。
*/
例子
@Data
@Document(indexName = "blog")
public class Article {
@Id
private String id;
private String title;
//FieldType.Nested 是 Elasticsearch 中的一种数据类型,用于支持嵌套文档的存储和查询。当一个文档中包含另一个文档作为其字段时,我们称之为嵌套文档。使用 FieldType.Nested 类型,可以将嵌套文档存储在 Elasticsearch 中,并支持复杂的查询操作。
@Field(type = FieldType.Nested, includeInParent = true)
private List<String> authors;
}
public interface ArticleRepository extends ElasticsearchRepository<Article, String>{
//findByAuthorsName名字必须按照一定的规则来写,自动帮我们生成crud的方法
page<Article> findByAuthorsName(String, Pageable pageable);
Optional<Article> findById(String id);
}
public void testSave(){
Article article = new Article();
article.setAuthors(asList("god","joker"))
articleRepository.save(article);
}
public void queryAuthorName(){
articleRepository.findByAuthorsName("god",PageRequest.of(0,10));
}
自定义 Elasticsearch 查询语句:
public interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("{\"bool\": {\"must\": [{\"match\": {\"title\": \"?0\"}}]}}")
List<Book> findByCustomQuery(String keyword);
}
ElasticsearchRepository命名规则
findBy{属性名}
: 根据指定属性的值进行精确匹配查询。findBy{属性名}Is
或findBy{属性名}
: 与findBy{属性名}
相同,用于精确匹配查询。findBy{属性名}Not
: 根据指定属性的值进行精确不匹配查询。findBy{属性名}IsNull
或findBy{属性名}Null
: 查询指定属性为 null 的数据。findBy{属性名}IsNotNull
或findBy{属性名}NotNull
: 查询指定属性不为 null 的数据。findBy{属性名}Like
: 根据指定属性的值进行模糊查询。findBy{属性名}NotLike
: 根据指定属性的值进行模糊不匹配查询。findBy{属性名}StartingWith
: 根据指定属性的值进行前缀匹配查询。findBy{属性名}EndingWith
: 根据指定属性的值进行后缀匹配查询。findBy{属性名}Containing
: 根据指定属性的值进行包含匹配查询。findBy{属性名}GreaterThan
: 查询指定属性值大于给定值的数据。findBy{属性名}LessThan
: 查询指定属性值小于给定值的数据。findBy{属性名}GreaterThanEqual
: 查询指定属性值大于等于给定值的数据。findBy{属性名}LessThanEqual
: 查询指定属性值小于等于给定值的数据。findBy{属性名}Between
: 查询指定属性值在给定范围内的数据。findBy{属性名}In
: 查询指定属性值在给定集合中的数据。findBy{属性名}NotIn
: 查询指定属性值不在给定集合中的数据。findBy{属性名}OrderBy{排序属性名}
: 根据指定属性进行排序查询。
注意:在命名规则中,属性名的首字母必须大写,且要与实体类中的属性名保持一致。同时,ElasticsearchRepository
还支持自定义查询方法,可以使用 @Query
注解来指定自定义的 Elasticsearch 查询语句。
Optional<>
Optional<>
是 Java 8 引入的一个类,它主要用于解决空指针异常(NullPointerException)的问题,并提供更优雅的方式处理可能为空的值。
在 Java 之前的版本中,当我们使用一个对象时,如果该对象为 null,调用它的方法或访问它的属性会导致空指针异常。为了避免这种情况,我们通常需要使用条件语句(例如 if-else)来检查对象是否为 null,然后再执行相应的操作。
Java 8 引入了 Optional<>
类,它将值包装在其中,并提供了一组方法来处理可能为空的值,避免了显式的空指针检查和条件语句。
Optional<>
类的主要特点包括:
- 可以包含一个非空值,也可以为空。
- 可以通过
isPresent()
方法判断是否包含非空值。 - 可以使用
get()
方法获取包含的非空值,但在调用之前最好使用isPresent()
方法进行检查,以避免空指针异常。 - 可以使用
orElse(T other)
方法在包含为空时提供一个默认值。 - 可以使用
orElseGet(Supplier<? extends T> other)
方法在包含为空时提供一个默认值的生成函数。 - 可以使用
orElseThrow(Supplier<? extends X> exceptionSupplier)
方法在包含为空时抛出指定的异常。
import java.util.Optional;
public class OptionalExample {
// 假设这个函数返回一个可能为空的字符串
public static Optional<String> getNullableString(boolean isNonNull) {
if (isNonNull) {
return Optional.of("Hello, World!");
} else {
return Optional.empty(); // 返回一个空的 Optional 对象
}
}
public static void main(String[] args) {
// 获取可能为空的字符串
Optional<String> optionalString = getNullableString(false);
// 使用 isPresent() 方法检查是否包含非空值
if (optionalString.isPresent()) {
String result = optionalString.get();
System.out.println("Value is present: " + result);
} else {
System.out.println("Value is empty.");
}
// 使用 orElse() 方法获取包含的值或提供默认值
String valueOrDefault = optionalString.orElse("Default Value");
System.out.println("Value or Default: " + valueOrDefault);
// 使用 orElseGet() 方法获取包含的值或通过 Supplier 提供默认值
String valueOrGeneratedDefault = optionalString.orElseGet(() -> generateDefault());
System.out.println("Value or Generated Default: " + valueOrGeneratedDefault);
// 使用 orElseThrow() 方法获取包含的值或在空时抛出异常
try {
String valueOrThrow = optionalString.orElseThrow(() -> new RuntimeException("Value is empty."));
System.out.println("Value or Throw: " + valueOrThrow);
} catch (RuntimeException e) {
System.out.println("Caught Exception: " + e.getMessage());
}
}
// 一个用于生成默认值的函数
public static String generateDefault() {
return "Generated Default Value";
}
}