基本增删改查
获取一个document
curl -X GET http://localhost:9200/index/type/id
获取同一type的所有元素
curl -X GET http://localhost:9200/index/type/_search
新增一个document
可以使用POST或PUT请求。
curl -X POST http://localhost:9200/index/type/id -d '{"field": "value",...}'
修改一个document
可以使用POST或PUT请求。
curl -X PUT http://localhost:9200/index/type/id -d '{"field": "value",...}'
删除一个document
curl -X DELETE http://localhost:9200/index/type/id
检索操作
基本语法如下:
curl -X POST http://localhost:9200/index/type/_search -d '{"query": {...}}'
match_all
匹配所有的文档
{"query": {"match_all": {}}}
match_none
和match_all相反,不匹配任何文档
{"query": {"match_none": {}}}
match
{"query": {"match": {"message": "hello world"}}}
match中检索的文本会被分词。默认来说分词后各个词组间的关系为or。该例子为查找出message字段包含hello或world的文档。
{"query": {"match" : {"message" : {"query" : "this is a test","operator" : "and"}}}}
通过增加operator参数,可以把默认的or关系修改为and。
match_phrase
{"query": {"match_phrase": {"name": "软件公司"}}}
匹配的文档要求“软件公司”这四个字必须都出现,且按照顺序出现。
{"query": {"match_phrase": {"name": {"query": "软件公司","slop": 1}}}}
slop用来指定各个分词匹配时的最大间隔,即“软件X公司”也会被匹配。
多字段匹配
{"query": {"multi_match" : {"query": "this is a test","fields": [ "subject", "message" ]}}}
分别用”subject”和”message”字段内容匹配”this is a test”,如果任意一个字段匹配,该文档会出现在检索结果中。
匹配的fields也可以使用星号作为通配符。
{"query": {"multi_match" : {"query": "Will Smith","fields": [ "title", "*_name" ]}}}
查询title和以名称以_name结尾的字段。
{"query": {"multi_match" : {"query" : "this is a test","fields" : [ "subject^3", "message" ]}}}
提升subject的score权重(3倍于message)。
term
term查询关键字不进行分词处理。
官方文档原文描述如下:
The term query finds documents that contain the exact term specified in the inverted index.
{"query": {"term": {"message": "some text"}}}
term的查询结果还与文档是否分词有关。如果文档内容不分词,大致相当于SQL中的”=”。
match和term的区别为:如果文档的有关字段进行了分词,match是搜索关键字的分词和文档字段的分词逐个比较,而term则是搜索关键字不分词,整个和文档字段的分词进行比较。
terms
{"query": {"terms" : { "message" : ["some", "text"]}}}
Query String 查询
{"query": {"query_string" : {"default_field" : "content","query" : "(new york city) OR (big apple)"}}}
将new york city和big apple分别交给分词器处理。
Range Query
范围查询
{"query": {"range" : {"age" : {"gte" : 10,"lte" : 20,"boost" : 2.0}}}}
可以使用的参数有:
- gt: greater than
- gte: greater than or equals
- lt: less than
-
Exists
字段存在查询
{"query": {"exists" : { "field" : "user" }}}
文档中user字段的值不能为null,user字段必须要存在。
Prefix
前缀查询
{"query": {"prefix" : { "user" : "pe" }}}
wildcard
通配符查询
{"query": {"wildcard" : { "user" : "pa*l" }}}
可以匹配paul或paal等。为了保证性能,最好不要在开头使用通配符(比如匹配*aul)。
通配符说明: 星号(*)匹配0个或多个字符
- 问号(?)匹配任意单个字符
中英文单字(字母)匹配场景
中文模糊搜索
{"query": {"match_phrase": {"name": "公司"}}}
match_phrase 的意思为短语匹配,不仅要匹配短语的字,而且这些字出现的顺序也必须要匹配
英文按字母模糊搜索
{"query": {"wildcard": {"name": "*aster*"}}}
布尔组合条件搜索
通过bool组合查询我们可以实现多个查询条件间and或or逻辑组合关系。例如:
{"query": {"bool": {"should": [{"wildcard": {"name": "*aster*"}}, {"match_phrase": {"authorList.name": "张"}}]}}}
bool组合查询内有多种子句:
- must 子句中的所有匹配必须都满足。
- must_not 和must相反,子句中的所有匹配必须都不满足。
- should 相当于或的关系,子句中的匹配只要至少有一个满足。如果存在must或filter子句,should中的条件默认不要求至少满足一个,即仅匹配must或filter子句且should中一个条件都不满足的文档也会被检索出来。如需设置至少满足的should条件个数,可以添加
minimum_should_match参数。 - filter 和must类似,不同的是搜索结果的匹配度评分会被忽略。
minimum_should_match示例:
{"query": {"bool": {"should": [{"wildcard": {"fieldList.fieldName": "*?0*"}},{"match_phrase": {"fieldName.fieldComments": "?0"}}],"filter": [{"term": {"systemId": "?1"}}],"minimum_should_match": 1}}}
以上查询不仅要求filter语句满足,而且should中的条件至少要满足一个。
Bool查询更详细的用法请参考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
嵌套对象字段的查询
{"query": {"match_phrase": {"author.name": "Paul Jackson"}}}
检索出author对象中的name字段值为Paul Jackson的文档。
SpringBoot 整合Elasticsearch
SpringBoot 官方以为我们做好了elasticsearch的整合。对于常见的操作,我们不必再去编写json请求报文。
SpringBoot和elasticsearch官方starter名为:springboot starter data elasticsearch。下面是这个starter的使用方法。
加入依赖
pom.xml加入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>
注意: Elasticsearch服务端版本号最好和springboot中依赖的elasticsearch.jar版本一致。 elasticsearch.jar的版本号可以通过查看项目依赖关系图得知。
建立Data Class
以Book这个类为例(使用了Project lombok)
Book.java:
@Document(indexName = "database", type = "book")@AllArgsConstructor@NoArgsConstructor@Datapublic class Book {private Long id;private String name;private List<Author> authorList; //支持嵌套元素}
Author.class
@Data@AllArgsConstructor@NoArgsConstructorpublic class Author {private String name;}
使用@Document注解来表示该bean是ES的文档,indexName为索引名称,type为索引类型。
注:可以使用@Field注解来修改字段默认的属性,比如是否索引,是否储存,使用什么分词器等。
建立Repository
public interface BookRepo extends ElasticsearchCrudRepository<Book, Long> {// 解析方法名方式List<Book> findAllByNameContains(String name);// 自定义Query JSON方式@Query("{\"bool\":{\"must\":[{\"match_phrase\":{\"authorList.name\":\"?0\"}}]}}")List<Book> matchPhrase(String phrase);}
Repository需要继承ElasticsearchCrudRepository<T, ID>接口。
Repository自定义方法命名规则和Spring Data JPA用法完全一致。同样可以加入Pageable参数实现分页查询。
可以使用@Query注解来自定义查询。
除此之外也可以通过NativeSearchQueryBuilder的方式来查询elasticsearch。
代码如下:
@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;@Testpublic void nativeQueryBuilderTest() {NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("authorList.name", "张三"))).build();List<Book> bookList = elasticsearchTemplate.queryForList(searchQuery, Book.class);System.out.println(bookList);}
我们使用QueryBuilders类来构造各种查询参数。
返回分页数据的例子:
@Autowiredprivate ElasticsearchTemplate elasticsearchTemplate;@Testpublic void nativeQueryBuilderTest() {NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(QueryBuilders.matchPhraseQuery("authorList.name", "张三"))).withPageable(PageRequest.of(0, 20)) //加上分页参数.build();Page<Book> books = elasticsearchTemplate.queryForPage(searchQuery, Book.class); //获取Page类型结果System.out.println(books.getContent());}
参考文档
Elasticsearch 官方文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
SpringBoot starter data elasticsearch官方文档: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/
作者:AlienPaul
链接:https://www.jianshu.com/p/72d21507a0b3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
