讲解ES的DSL查询
match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找
默认多个词是or关系,只要有一个词匹配就会查询出来
GET /[索引名称]/_search
{
"query":{
"match":{
"字段名":{
"query":"值",
"operator":"and",
"fuzziness": 2
"minmum_should_match":2
}
}
}
}
match_phrase查询分析文本并根据分析的文本创建一个短语查询。match_phrase会将检索关键词分词。match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的
GET /[索引名称]/_search
{
"query":{
"match_phrase":{
"address":{
"query":"广州白云山",
"slop":2
}
}
}
}
可以根据字段类型,决定是否使用分词查询,得分最高的在前面
就是一个值同时匹配多个字段
GET /[索引名称]/_search
{
"query":{
"multi_match":{
"query":"值",
"fields":["字段1","字段2"]
}
}
}
字段类型分词,将查询条件分词之后进行查询,如果该字段不分词就会将查询条件作为整体进行查询
允许我们在单个查询字符串中指定AND | OR | NOT条件,同时也和multi_match query一样,支持多字段搜索。和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛
// 不指定字段就是匹配所有字段
// 指定字段查询
GET /[index]/_search
{
"query":{
"query_string":{
"default_field":"字段名",
"query":"白云山 OR 橘子洲"
}
}
}
// 多字段查询
GET /[index]/_search
{
"query":{
"query_string":{
"fields":["字段名1","字段名2"],
"query":"张三 OR (广州 AND 王五)"
}
}
}
查询字段分词就将查询条件分词查询,查询字段不分词将查询条件不分词查询
or and 啥的不要用小写
类似Query String,但是会忽略错误的语法,同时只支持部分查询语法,不支持AND OR NOT,会当作字符串处理
GET /[index]/_search
{
"query":{
"simple_query_string":{
"fields":["字段名1","字段名2"],
"query":"张三 | (广州 + 王五)",
"default_operator":"AND" // 可以忽略和+使用一个即可
}
}
}
Term用来使用关键词查询(精确匹配),还可以用来查询没有被进行分词的数据类型。Term是表达语意的最小单位,搜索和利用统计语言模型进行自然语言处理都需要处理Term
match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找,而term会直接对关键词进行查找。一般模糊查找的时候,多用match,而精确查找时可以使用term
在ES的Mapping Type 中 keyword , date ,integer, long , double , boolean ip 这些类型不分词,只有text类型分词
GET /[索引名称]/_search
{
"query":{
"term":{
"字段名":{
"value":"值"
}
}
}
}
GET /[索引名称]/_search
{
"query":{
// 避免算分,而且term可以利用缓存
"constant_score":{
"filter":{
"term":{
// text是有子类型的,这样精确匹配就可以了
"address.keyword":"广州白云山公园"
}
}
}
}
}
可以通过 Constant Score 将查询转换成一个 Filtering,避免算分,并利用缓存,提高性能
指定多个ip匹配文档
GET /[索引名称]/_search
{
"query":{
"ids":{
"values":[1001,1002]
}
}
}
批量查询根据id
GET /[索引名称]/_mget
{
"docs":[
{"index":"索引名","_id":id值},
{"index":"索引名","_id":id值}
]
}
GET /[索引名称]/_mget
{
"ids":["1","2"]
}
暂时省略
它会对分词后的term进行前缀搜索
它不会分析要搜索字符串,传入的前缀就是想要查找的前缀
默认状态下,前缀查询不做相关度分数计算,它只是将所有匹配的文档返回,然后赋予所有相关分数值为1。它的行为更像是一个过滤器而不是查询。两者实际的区别就是过滤器是可以被缓存的,而前缀查询不行
需要遍历所有倒排索引,并比较每个term是否已所指定的前缀开头
所以有性能问题
GET /[索引名称]/_search
{
"query":{
"prefix":{
"字段名":{
"value":"值"
}
}
}
}
通配符查询:工作原理和prefix相同,只不过它不是只比较开头,它能支持更为复杂的匹配模式
GET /[索引名称]/_search
{
"query":{
"wildcard":{
"字段名":{
"value":"*白*"
}
}
}
}
范围查询
# 大于等于10小于等于20,gte大于等于,gt大于,lt小于,lte小于等于
GET /[索引名称]/_search
{
"query":{
"range":{
"字段名":{
"gte":10,
"lte":20
}
}
}
}
GET /[索引名称]/_search
{
"query":{
"range":{
"date":{
// 2年之前的数据
"gte":"now-2y"
}
}
}
}
在实际的搜索中,我们有时候会打错字,从而导致搜索不到。在Elasticsearch中,我们可以使用fuzziness属性来进行模糊查询,从而达到搜索有错别字的情形
GET /es_db/_search
{
"query": {
"fuzzy": {
"address": {
"value": "白运山",
"fuzziness": 1
}
}
}
}
GET /es_db/_search
{
"query": {
"match": {
"address": {
"query": "广洲",
"fuzziness": 1
}
}
}
}
一个bool查询,是一个或者多个查询子句的组合,总共包括4种子句,其中2种会影响算分,2种不影响算分
如果多条查询子句被合并为一条复合查询语句,比如 bool查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中
GET /[索引名称]/_search
{
"query":{
"bool":{
"must":[
{"term":{"city":"上海"}}
],
"should":[
{"term":{"brand":"皇冠假日"}},
{"term":{"brand":"华美达"}}
],
"must_not":[
{"range":{"price":{"lte":500}}}
],
"filter":[
{"range":{"score":{"gte":45}}}
]
}
}
}