欢迎投稿

今日深度:

Elasticsearch-查询表达式,elasticsearch-

Elasticsearch-查询表达式,elasticsearch-


查询表达式(QUERY DSL)是一种非常灵活又富有表现力的查询语言。Elasticsearch使用它可以以简单的JSON接口来展现搜索引擎功能的绝大部分。在你的应用中,你应该用它来编写你的查询语句。它可以使你的查询语句更灵活、更精确、易读和易调试。

要使用这种查询表达式,只需将查询条件传递给query参数:

{
    "query":...
}

空查询,查询索引库中所有的文档:

{

}

等价于:

{
    "query":{
        "match_all":{}
    }
}

查询语句的结构

一个简单的查询语句,它的结构是:

{
    QUERY_NAME:{
        ARGUMENT:VALUE,
        ARGUMENT:VALUE,
        ...
    }
}

如果是针对某个字段,它的结构如下:

{
    QUERY_NAME:{
        FIELD_NAME:{
            ARGUMENT:VALUE,
            ARGUMENT:VALUE,
            ...
        }
    }
}

举个栗子,你可以使用match查询语句来查询name包含的所有数据:

{
    "match":{
        "name":"张"
    }
}

完整的请求体如下:

{
    "query":{
        "match":{
            "name":"张"
        }
    }
}

一些重要的查询

虽然Elasticsearch自带了很多的查询。但经常用到的就那么几个。接下来将介绍几个常用的查询:

match_all查询

match_all查询,为查询所有文档。在没有指定查询方式时,它是默认的查询:

{
    "query":{
        "match_all":{}
    }
}

match查询

无论你在任何字段上进行的是全文搜索还是精确值查询,match查询是你可用的标准查询。如果你在一个全文字段上使用match查询,在执行查询前,它将用正确的分析器去分析查询字符串:

{
    "query":{
        "match":{
            "name":"张"
        }
    }
}

multi_match查询

multi_match可以在多个字段上进行相同的match查询:

{
    "multi_match":{
        "query":"query info",
        "fields":["name","addr"]
    }
}

range查询

range查询出落在指定区间内的时间或数字:

{
    "range":{
        "age":{
            "gte":18,
            "lte":22
        }
    }
}

range查询相关区间运算符:
- gt:大于
- lt:小于
- gte:大于或等于
- lte:小于或等于

term查询

term查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些not analyzed的字符串:

{
    "query":{
        "term":{
            "date":"2017-10-30"
        }
    }
}

term查询对于输入的文本不分析,所以它将给定的值进行精确查询。它查询那些精确匹配的值(包括大小写,重音和空格等方面的差异)

terms查询

terms查询和term查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值的任何一个值,那么这个文档满足条件:

{
    "query":{
        "terms":{
            "date":["2017-10-30","2017-10-31"]
        }
    }
}

exists和missing查询

exists用于查询字段存在的文档,而missing用于查询字段不存在的文档。这与MongoDB中exists=trueexists=fasle有这相同的特性:

{
    "query":{
        "exists":{
            "field":"name"
        }
    }
}

上述栗子用于查询name字段存在的所有文档。

组合多查询

在现实的开发过程中,查询的需求往往没有那么简单,不可能只查询一个条件就能满足我们的需求,往往需要查询多个条件,同时满足或者满足其中一个或这两个条件才是我们所需要的。为了构建类似的高级查询,你需要有一种能将多查询组合成一个单一查询的方法。

你可以用bool查询来实现一系列需求。这种查询可以将多个查询组合在一起,成为用户自己所需要的bool查询,它接收一下参数:

  • must:文档必须匹配这些条件才能被包含进来
  • must_not:文档必须不匹配这些条件才能被包含进来
  • should:如果满足这些语句中的任意语句,将增加_score,否则将无任何影响
  • filter:必须匹配,但它以不评分、过滤模式来进行

举个栗子:

{
    "query":{
        "bool":{
            "must":{"match":{"name":"laowang"}},
            "must_not":{"term":{"age":18}},
            "should":[
                {
                    "match":{
                        "addr":"广东"
                    }
                },
                {
                    "match":{
                        "addr":"广西"
                    }
                }
            ]
        }
    }

}

匹配name = laowang并且age != 18,并且addr=广东或者addr=广西的所有文档。如果文档满足should中的任一条件_score值将更高,排名将靠前。如果都满足,_score将会更高。排名更靠前

Elasticsearch默认是按照_score进行排序的,而_score的大小是根据文档的匹配程度来决定的,filter查询对查询到的所有文档不进行评分,即查询到的数据是无序的。bool也可以嵌套在filter中进行一个不评分的查询,如下所示:

{
    "query":{
        "bool":{
            "must":{"match":{"name":"laowang"}},
            "filter":{
                "bool":{
                    "must":{"match":{"age":18}}
                }
            }
        }
    }
}

值得注意的是filter必须嵌套在bool或其他查询中,不可单独拿出来使用

验证查询语句是否合法

当我们执行一个很复杂的查询语句时,我们可以用validate-queryAPI来验证这个查询语句是否合法:

curl -XGET 'http://localhost:9200/csdn/blog/_validate/query' -d '
{
    "query":{
        "name":{
            "match":"laowang"
        }
    }
}
'

将会返回如下信息:

{
  "valid": false
}

validfalse表示,查询语句不合法。只有vaild信息是远远不够的,我们还需要知道错误的原因是什么?我们可以将explain参数添加到查询当中:

curl -XGET 'http://localhost:9200/csdn/blog/_validate/query?explain' -d '
{
    'query':{
        "name":{
            "match":"laowang"
        }
    }    
}
'

将返回如下信息:

{
  "valid": false,
  "error": "org.elasticsearch.common.ParsingException: no [query] registered for [name]"
}

错误信息告诉我们,Elasticsearch中没有name查询表达式。

www.htsjk.Com true http://www.htsjk.com/Elasticsearch/33587.html NewsArticle Elasticsearch-查询表达式,elasticsearch- 查询表达式(QUERY DSL)是一种非常灵活又富有表现力的查询语言。Elasticsearch使用它可以以简单的JSON接口来展现搜索引擎功能的绝大部分。在你的应用中...
相关文章
    暂无相关文章
评论暂时关闭