Elasticsearch 常用查询

236 阅读8分钟

Elasticsearch 常用查询

es入门使用
es索引使用
es分词使用

常用条件查询搜索

# 查看索引库
GET /elasticsearch_test/


# 查看所有
GET /elasticsearch_test/_search


# 全文搜索
# 全文搜索能够搜索已分析的文本字段,
# 使用索引期间应用于统一分析器处理查询字段
# 全文搜索分为匹配搜索和短语搜索、query_string、多字段匹配搜索

GET /elasticsearch_test/_search
{
  "query": {
    "match_all": {
    }
  }
}

# 匹配搜索
# 可以对一个字段进行匹配 模糊查询,接收一个文本对其进行分词分析
# 再组织成一个布尔查询,可以通过operator组成一个组合操作,or and 默认是or


# or
# spring cloud实战  分词查询 spring 、 cloud 、 实战 这三个or的关系
POST /elasticsearch_test/_search 
{
  "query": {
    "match": {
      "description": "spring cloud实战"
    }
  }
}

# and
# spring cloud实战  分词查询 spring 、 cloud 、 实战 这三个and 的关系
POST /elasticsearch_test/_search 
{
  "query": {
    "match": {
      "description":{
      "query": "spring cloud实战",
      "operator": "and"
    }
  }
  }
}

# 短语搜索

# 用来只对一个字段进行短语查询 可以指定analyzer、 slop移动因子

POST /elasticsearch_test/_search
{
  "query": {
    "match_phrase": {
      "description": {
        "query": "cloud实战",
        "slop": 0
      }
    }
  }
}

## query_string 不需要指定字段即进行全文搜索查询,同时也可以指定在那些字段上查询

# 默认 

POST /elasticsearch_test/_search 
{
  
  "query": {
    "query_string": {
      "query": "实战"
    }
  }
  
}

# 指定字段
POST /elasticsearch_test/_search 
{
  
  "query": {
    "query_string": {
      "query": "实战",
      "default_field": 
        "description"
 
    }
  }
  
}

# 逻辑查询 
# AND OR必须大写 默认OR
POST /elasticsearch_test/_search 
{
  
  "query": {
    "query_string": {
      "query": "spring AND 实战",
      "default_field": 
        "description"
 
    }
  }
  
}


# 模糊查询

# ~2 表示默认 2 表示向后模糊几个分词
POST /elasticsearch_test/_search 
{
  
  "query": {
    "query_string": {
      "query": "golang~2",
      "default_field": 
        "name"
 
    }
  }
  
}


# 多字段支持
POST /elasticsearch_test/_search 
{
  
  "query": {
    "query_string": {
      "query": "golang~2",
        "fields": ["description","name"]
  }
  
}

}



# 使用*匹配多字段
POST /elasticsearch_test/_search 
{
  
  "query": {
    "query_string": {
      "query": "golang~2",
        "fields": ["description","n*"]
  }
  
}

}




# 词条级搜索 term查询
# 精确化查找,与全文相反,不分析搜索词,词条和存在字段中的术语内容完全匹配

POST /elasticsearch_test/_search
{
  "query": {
    "term": {
      "price":   "100"
      
    }
  }
}

POST /elasticsearch_test/_search
{
  "query": {
    "term": {
      "studymodel":   "201001"
      
    }
  }
}

# 不能完全匹配
POST /elasticsearch_test/_search
{
  "query": {
    "term": {
      "description":   "spring cloud实战"
      
    }
  }
}


# terms 词条集合搜索
POST /elasticsearch_test/_search
{
  "query": {
    "terms": {
      "description":  [ "spring","cloud","实战"]
      
    }
  }
}


# 范围查询
POST /elasticsearch_test/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 10,
        "lte": 200
      }
      
    }
  }
}

POST /elasticsearch_test/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 10,
        "lte": 200
      }
      
    }
  }
}


# 时间范围以及格式化
GET /elasticsearch_test/_search
{
  "query": {
    "range": {
      "timestamp": {
        "gte": "10/07/2020",
        "lte":"10/12/2022",
        "format": "dd/MM/yyyy"
      }
      
    }
  }
}


# 不为空查询
# 相当于sql中 is not null
GET /elasticsearch_test/_search
{
  "query": {
    "exists": {
      "field": "price"
    }
  }
}


# 词项前缀
# name字段 s开头的
GET /elasticsearch_test/_search
{
  "query": {
    "prefix": {
      "name": "s"
    }
  }
}


# 通配符

# spring s*r*
GET /elasticsearch_test/_search
{
  "query": {
    "wildcard": {
      "name": "s*r*"
    }
  }
}


# boost 通配符 后几个
GET /elasticsearch_test/_search
{
  "query": {
    "wildcard": {
      "name": {
        "value": "s*",
        "boost": 8
      
    }
  }
}
}


# 正则搜索
GET /elasticsearch_test/_search
{
  "query": {
    "regexp": {
      "name":"s.*"
  }
}
}


# 模糊搜索

GET /elasticsearch_test/_search
{
  "query": {
    "fuzzy": {
      "name":"golang"
  }
}
}


GET /elasticsearch_test/_doc/2

# id集合搜索
GET /elasticsearch_test/_search
{
  "query": {
    "ids": {
      "values": ["1","2"]
    }
}
}

排序


# 排序

#  _score 排序
GET /elasticsearch_test/_search
{
"sort": [
  {"_score":"asc"},
  
  {
    "price": {
      "order": "desc"
    }
  }
]
}

#  字段排序
GET /elasticsearch_test/_search
{
  "query": {
  
    "query_string": {
      "default_field": "description",
      "query": "spring or go"
    }
   
},
"sort": [
  {
    "price": {
      "order": "desc"
    }
  }
]
}


#多字段排序

#  _score 排序
GET /elasticsearch_test/_search
{
  "query": {
  
    "query_string": {
      "default_field": "description",
      "query": "spring or go"
    }
   
},
"sort": [
  {"_score":"asc"},
  
  {
    "price": {
      "order": "desc"
    }
  },
  
    {
    "_id": {
      "order": "asc"
    }
  }
]
}

常用 DSL 查询



#
GET /elasticsearch_test/_search
{
  "profile": "true"
}

GET /elasticsearch_test/_search
{
  "query": {
    "fuzzy": {
      "name":""
  }
}
}

GET /elasticsearch_test/_mapping


GET /elasticsearch_test/_search
{
  "query": {
    "match": {
      "description": "spring"
    }
  }
}



POST /elasticsearch_test/_doc/
{
           
          "price" : 9,
          "studymodel" : "  0",
          "name" : "java",
          "description" : "java 开发相关知识",
          "timestamp" : "2023-04-19 16:33:09"
         
}
      

# 查询所有,默认查 10 条数据,可以设置值
# _search查询默认采用的是分页查询,每页记录数size的默认值为10
# size可以无限增加吗不可以。建议使用深度分页查询
GET /elasticsearch_test/_search
{
  "from": 0,
  "size": 20, 
  "query": {
    "match_all": {}
  }
}


#  深分页查询Scroll 然后根据 scroll id 查询下一页
GET /elasticsearch_test/_search?scroll=1m
{
  "from": 0, 
  "size": 2, 
  "query": {
    "match_all": {}
  }
}

# 下一页
# 多次根据scroll_id游标查询,直到没有数据返回则结束查询。采用游标查询索引全量数据, 更安全高效,限制了单次对内存的消耗。
GET /_search/scroll
{
  "scroll": "1m", 
  "scroll_id":"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkR5T2lJWGR3U2VTcmVLU1JpQzJlcHcAAAAAAAAAbxZnYjRHblhUVFJCaXd6bklRWTV2OUdn"
}

# 返回指定字段_source
GET /elasticsearch_test/_search
{
  "query": {
    "match_all": {
      
    }
    
  },"_source":["name"]
}








# match
# match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找
# 单个字段查询
# 分词后 and的效果 表示都满足,默认是or 或者
GET /elasticsearch_test/_search
{
  "query": {
    "match": {
      "description": {
        "query": "java golang", 
        "operator": "and"
        }
    }
  }
}


#  当operator参数设置为or时,minnum_should_match参数用来控制 匹配的分词的最少数量。
# 最少匹配的分词数量
# 1 表示只满足一个即可
GET /elasticsearch_test/_search
{
  "query": {
    "match": {
      "description": {
        "query": "java golang", 
        "operator": "or",
        "minimum_should_match": 1
        }
    }
  }
}

# 2 表示 2 个分词都得满足
GET /elasticsearch_test/_search
{
  "query": {
    "match": {
      "description": {
        "query": "java golang", 
        "operator": "or",
        "minimum_should_match": 2
        }
    }
  }
}


# 短语查询match_phrase
# match_phrase查询分析文本并根据分析的文本创建一个短语查询。match_phrase 会将检 索关键词分词。match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必 须相同,而且默认必须都是连续的。
GET /elasticsearch_test/_search
{
  "query": {
    "match_phrase": {
      "description": "广州白云山"
    }
  }
}

# 为什么查询广州白云山有数据,
# 先查看广州白云山公园分词结果,可以知道广州和白云不是相邻的词条,中间会隔一个白云 山,而match_phrase匹配的是相邻的词条,所以查询广州白云山有结果,但查询广州白云 没有结果。
# match_phrase匹配的是相邻的词条
# 没有分词成广州 白云


GET /_analyze
{
  "analyzer": "ik_max_word", 
  "text": "广州白云山"
}

# 查询
# 广州云山分词后相隔为2,可以匹配到结果
GET /elasticsearch_test/_search
{
  "query": {
    "match_phrase": {
      "description": {
        "query": "广州白云山",
        "slop": 2
      }
      
    }
  }
}



# 多字段查询multi_match
# 可以根据字段类型,决定是否使用分词查询,得分最高的在前面
# 注意:字段类型分词,将查询条件分词之后进行查询,如果该字段不分词就会将查询条件作 为整体进行查询

GET /elasticsearch_test/_search
{
  "query": {
    "multi_match": {
      "query": "golang 白云",
        "fields": ["description"]
      
    }
  }
}



#

# query_string 允许我们在单个查询字符串中指定AND | OR | NOT条件,同时也和 multi_match query 一样,支持多字段搜索。和match类似,但是match需要指定字段名,query_string是在所 有字段中搜索,范围更广泛。 注意: 查询字段分词就将查询条件分词查询,查询字段不分词将查询条件不分词查询

# 不指定
GET /elasticsearch_test/_search
{
  "query": {
    "query_string": {
      "query": "java and 开发 "
    }
  }
}

GET /elasticsearch_test/_search
{
  "query": {
    "query_string": {
      "default_field": "description", 
      "query": "java and 开发 "
    }
  }
}

# 指定字段
GET /elasticsearch_test/_search
{
  "query": {
    "query_string": {
      "fields": ["name","description"],
      "query": "java or golang (java and 开发) "
    }
  }
}


# 关键词查询Term
# Term查询,对输入不做分词。会将输入作为一个整体,在倒排索引中查找准确的 词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分
GET /elasticsearch_test/_search
{
  "query": {
    "term": {
      "name": {
        "value": "java"
      }
    }
  }
}

GET /elasticsearch_test/_search
{
  "query": {
    "term": {
      "name": {
        "value": "广州白云山"
      }
    }
  }
}

# 批量添加 必须按行,且
PUT /elasticsearch_test/_bulk
{"index":{"_id":10}}
{"price" :  160, "studymodel" : " 123","name" : "Suzhou苏州一日游","description" : " 苏州一日游,苏州园林,平江路,山塘街,带你体验江南水乡。","timestamp" : "2023-04-19 16:33:09"}
{"index":{"_id":11}}
{"price" :  260,"studymodel" : " 123","name" : "suZhou苏州一日游","description" : " 苏州一日游,苏州 寒山寺,东方之门,金鸡湖,带你体验江南水乡。","timestamp" : "2023-04-19 16:33:09"}






PUT /product

POST /product/_create


GET /product/_mapping

POST /product/_doc
{
  "name":"iPhone",
  "price":2001
}


GET /product/_search
{
  "query": {
    "match_all": {}
  }
}

# 大写查不出来
GET /product/_search
{
  "query": {
    "term": {
      "name": "iPhone"
    }
  }
}

# 关闭

GET /product/_analyze
{
  "analyzer": "standard",
  "text": "iPhone"
}

# 分析结果 被转为iphone了 , 对于英文,可以考虑建立索引时忽略大小写 

# 删除索引
DELETE /product

# 映射以及 忽略大小写 
PUT /product
{
  "settings": {
    "analysis": {
      "normalizer": {
        "es_normalizer": {
          "filter": [
            "lowercase",
            "asciifolding"
          ],
          "type": "custom"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword",
        "normalizer": "es_normalizer", 
        "index": "true",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "price": {
        "type": "long"
      }
    }
  }
}



# 可以通过 Constant Score 将查询转换成一个 Filtering,避免算分,并利用缓存,提高性 能。 将Query 转成 Filter,忽略TF-IDF计算,避免相关性算分的开销 Filter可以有效利用缓存

GET /product/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "name": "iPhone"
        }
      }
    }
  }
}


# ES中的结构化搜索

# 结构化搜索(Structured search)是指对结构化数据的搜索。

# 应用场景:对bool,日期,数字,结构化的文本可以利用term做精确匹配


POST /employee/_bulk 
{"index":{"_id":1}} 
{"name":"小明","interest":["跑步","篮球"]} 
{"index":{"_id":2}} 
{"name":"小红","interest":["跳舞","画画"]} 
{"index":{"_id":3}} 
{"name":"小丽","interest":["跳舞","唱歌","跑步"]}

# term处理多值字段,term查询是包含,不是等于
GET /employee/_search
{
  "query": {
    "term": {
      "interest.keyword": {
        "value": "跳舞"
      }
    }
  }
}

# 多值字段 多条件查询 方法1
GET /employee/_search
{
  "query": {
    "bool": {
      "filter": [
      {
        "term": {
          "interest.keyword": {
            "value": "跳舞"
          }
        }
      },
      {
        "term": {
          "interest.keyword": {
            "value": "跑步"
          }
        }
      }
    ]
    }
  }
}

# 多值字段 多条件查询 方法2
GET /employee/_search
{
  "query": {
    
        "bool": {
          "filter": [
          "term": {
          "interest":  ["跳舞","跑步"]
          
        }
          ]
        }
      
  
  }
}

# 日期range
PUT /date_el

GET /date_el/_mapping

POST /date_el/_bulk
{"index":{"_id":1}}
{"price":100,"daye":"2023-04-30","msg":"苹果 11 pro"}
{"index":{"_id":2}}
{"price":100,"daye":"2023-04-30","msg":"苹果 12 pro"}



GET /date_el/_search
{
  "query": {
    "range": {
      "daye": {
        "gte": "2020-01-01",
        "lte": "2023-05-01"
      }
    }
  }
}


# now-2d 表示当天天-2 年月日同理 
GET /date_el/_search
{
  "query": {
    "range": {
      "daye": {
        "gte": "now-2d",
        "lte": "now"
      }
    }
  }
}

# now+2d 表示后 2 天
GET /date_el/_search
{
  "query": {
    "range": {
      "daye": {
        "lte": "now+2d"
      }
    }
  }
}

# 查不到 -20h
GET /date_el/_search
{
  "query": {
    "range": {
      "daye": {
        "lte": "now-20h"
      }
    }
  }
}

# 查到 -2h
GET /date_el/_search
{
  "query": {
    "range": {
      "daye": {
        "lte": "now-2h"
      }
    }
  }
}


# 多id查询ids
GET /date_el/_search
{
  "query": {
    "ids":{
      "values":  [1,2,3]
    }
  }
}


# 模糊查询fuzzy

# 在实际的搜索中,我们有时候会打错字,从而导致搜索不到。在Elasticsearch中,我们可以 使用fuzziness属性来进行模糊查询,从而达到搜索有错别字的情形

#fuzziness:表示输入的关键字通过几次操作可以转变成为ES库里面的对应field 的字段操作是指:新增一个字符,删除一个字符,修改一个字符,每 次操作可以记做编辑距离为1,默认是 0

#fuzzy 模糊查询 最大模糊错误 必须在0-2之间 搜索关键词长度为 2,不允许存在模糊 搜索关键词长度为3-5,允许1次模糊 搜索关键词长度大于5,允许最大2次模糊

GET /elasticsearch_test/_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "jav",
        "fuzziness": 1
      }
    }
  }
}