参考地址:https://my.oschina.net/u/1792341/blog/911383
https://www.cnblogs.com/wenbronk/p/6432990.html
导入所需maven依赖
<properties>
<elasticsearch.version>7.2.1</elasticsearch.version>
</properties>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
连接服务器
private static RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(
new HttpHost("192.168.1.100", 9200, "http")));
查询介绍
Match查询
此查询将文本或短语与一个或多个字段的值相匹配。例如,
POST /schools*/_search
{
"query":{
"match" : {
"city":"pune"
}
}
}
multi_match查询
此查询将文本或短语与多个字段匹配。例如
POST /schools*/_search
{
"query":{
"multi_match" : {
"query": "hyderabad",
"fields": [ "city", "state" ]
}
}
}
Query String查询
该查询使用查询解析器和query_string关键字。例如
POST /schools/_search
{
"query":{
"query_string":{
"query":"good faculty"
}
}
}
Term查询
这些查询主要处理数字、日期等结构化数据。例如
POST /schools/_search
{
"query":{
"term":{"zip":"176115"}
}
}
Range查询
该查询用于查找值在值范围之间的对象。为此,我们需要使用如下运算符
- gte:大于等于
- gt:大于
- lte:小于等于
lt:小于
举个例子:
POST /schools*/_search
{
"query":{
"range":{
"rating":{
"gte":3.5
}
}
}
}
其他类型的term级查询有:
- Exists查询:判断某个字段具有非空值。
- Missing查询:与Exists查询相反,该查询搜索没有特定字段或字段值为空的对象。
- Wildcard or regexp查询:该查询使用正则表达式来查找对象中的模式。
- Type query查询:特定类型的文档。例如,
POST /schools*/_search
{
"query":{
"type" : {
"value" : "school"
}
}
}
复合查询
这些查询是通过使用布尔运算符(如and、or、not或for不同索引或具有函数调用等)彼此合并的不同查询的集合。例如
POST /schools*/_search
{
"query":{
"filtered":{
"query":{
"match":{
"state":"UP"
}
},
"filter":{
"range":{
"rating":{
"gte":4.0
}
}
}
}
}
}
Joining查询
这些查询用于包含多个映射或文档的情况。有两种类型的joining查询:
嵌套查询
这些查询处理嵌套映射(您将在下一章中了解更多)。
has_child和has_parent查询
这些查询用于检索在查询中匹配的文档的子文档或父文档。例如,
POST /tutorials/_search
{
"query":
{
"has_child" : {
"type" : "article", "query" : {
"match" : {
"Text" : "This is article 1 of chapter 1"
}
}
}
}
}
地理位置查询
这些查询处理地理位置,这些查询有助于找到指定位置附近的学校或任何其他地点。您需要使用地理点数据类型。例如,
POST /schools*/_search
{
"query":{
"filtered":{
"filter":{
"geo_distance":{
"distance":"100km",
"location":[32.052098, 76.649294]
}
}
}
}
}
总结
match query搜索的时候,首先会解析查询字符串,进行分词,然后查询,而term query,输入的查询内容是什么,就会按照什么去查询,并不会解析查询内容,对它分词。
**简单的matchQuery 查询的内容会通过分词,分词后的数据进行检索,只要包含其中一个分词就会被检索出来
searchRequestBuilder.setQuery(QueryBuilders.matchQuery("fieldD", "bigData is magic"));
matchPhraseQuery 查询的内容通过分词,严格按照分词的出现的顺序进行查询,也就是必须包含所有分词,且出现数据一致
searchRequestBuilder.setQuery(QueryBuilders.matchPhraseQuery("fieldD", "bigData spark is magic"));
询的字段是进行分词索引的,如果不是分词索引则不生效, 如果只是查询 bigData magic ,则这种查询是查询不到的,需要完全匹配,如果想要查询到,需要设置slop(2),需要这样查询
searchRequestBuilder.setQuery(QueryBuilders.matchPhraseQuery("fieldD", "bigData spark is magic").slop(2))
termQuery 词精确查询,fieldD 分词后包含 bigData的term的文档
searchRequestBuilder.setQuery(QueryBuilders.termQuery("fieldD", "bigData"));
terms Query 多term查询,查询fieldD 包含 bigData spark或storm 中的任何一个或多个的文档
searchRequestBuilder.setQuery(QueryBuilders.termsQuery("fieldD", "bigData","spark","storm"));
rangeQuery 范围查询字段fieldB 大于20并且小于50 包含上下界
searchRequestBuilder.setQuery(QueryBuilders.rangeQuery("filedB").gt("20").lt("50").includeLower(true).includeUpper(true));
prefixQuery 匹配分词前缀 如果字段没分词,就匹配整个字段前缀
searchRequestBuilder.setQuery(QueryBuilders.prefixQuery("fieldD","spark"));
wildcard query 通配符查询,支持* 任意字符串;?任意一个字符
searchRequestBuilder.setQuery(QueryBuilders.wildcardQuery("fieldD","spark*"));
Fuzzy query 分词模糊查询,通过增加fuzziness 模糊属性,来查询term 如下 能够匹配 fieldD 为 spar park spark前或后加一个字母的term的 文档 fuzziness 的含义是检索的term 前后增加或减少n个单词的匹配查询
searchRequestBuilder.setQuery(QueryBuilders.fuzzyQuery("fieldD","spark").fuzziness(Fuzziness.ONE));
QueryStringQueryBuilder 使用的默认的分词导致的。
在没有给QueryStringQueryBuilder 指定特定的分词器时,ES会用默认的analyzer来处理,也就是名字(logical name)为default, default_index, default_search的analyzer。
ES内置的一些analyzer。
analyzer | logical name | description |
---|---|---|
standard analyzer | standard | standard tokenizer, standard filter, lower case filter, stop filter |
simple analyzer | simple | lower case tokenizer |
stop analyzer | stop | lower case tokenizer, stop filter |
keyword analyzer | keyword | 不分词,内容整体作为一个token(not_analyzed) |
pattern analyzer | whitespace | 正则表达式分词,默认匹配\W+ |
language analyzers | lang | 各种语言 |
snowball analyzer | snowball | standard tokenizer, standard filter, lower case filter, stop filter, snowball filter |
custom analyzer | custom | 一个Tokenizer, 零个或多个Token Filter, 零个或多个Char Filter |
这个情况会使ES检索时,会对中文进行最小粒度的切分,例如:
new QueryStringQueryBuilder("客服").field("title").defaultOperator(Operator.AND);
则ES检索时,会将“客服” 拆分成 “客”,“服”,检索的结果为title中有 “客”,“服”两个字的即可,不需要两个字相邻,如果需要检索包含“客服”的,加上 双引号 表示强制要求 拆分一起,则需要写成:
new QueryStringQueryBuilder("\""+"客服"+"\"").field("title").defaultOperator(Operator.AND);