zoukankan      html  css  js  c++  java
  • ElasticSearch search api的基础语法+Query DSL搜索+filter与query对比+组合查询+定位不合法的搜索

    一. search api的基础语法

    1、search语法


    GET /search
    {}

    GET /index1,index2/type1,type2/search
    {}

    GET /_search
    {
    "from": 0,
    "size": 10
    }


    2、http协议中get是否可以带上request body

    HTTP协议,一般不允许get请求带上request body,但是因为get更加适合描述查询数据的操作,因此还是这么用了


    GET /_search?from=0&size=10

    POST /_search
    {
    "from":0,
    "size":10
    }


    碰巧,很多浏览器,或者是服务器,也都支持GET+request body模式

    如果遇到不支持的场景,也可以用POST /_search

     二.Query DSL搜索

    1、什么是Query DSL


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


    2、Query DSL的基本语法

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

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

    示例:


    GET /test_index/test_type/_search
    {
    "query": {
    "match": {
    "test_field": "test"
    }
    }
    }


    3、如何组合多个搜索条件

    搜索需求:title必须包含elasticsearch,content可以包含elasticsearch也可以不包含,author_id必须不为111


    {

    "took": 1,
    "timed_out": false,
    "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
    },
    "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
    {
    "_index": "website",
    "_type": "article",
    "_id": "2",
    "_score": 1,
    "_source": {
    "title": "my hadoop article",
    "content": "hadoop is very bad",
    "author_id": 111
    }
    },
    {
    "_index": "website",
    "_type": "article",
    "_id": "1",
    "_score": 1,
    "_source": {
    "title": "my elasticsearch article",
    "content": "es is very bad",
    "author_id": 110
    }
    },
    {
    "_index": "website",
    "_type": "article",
    "_id": "3",
    "_score": 1,
    "_source": {
    "title": "my elasticsearch article",
    "content": "es is very goods",
    "author_id": 111
    }
    }
    ]
    }
    }


    GET /website/article/_search
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "title": "elasticsearch"
    }
    }
    ],
    "should": [
    {
    "match": {
    "content": "elasticsearch"
    }
    }
    ],
    "must_not": [
    {
    "match": {
    "author_id": 111
    }
    }
    ]
    }
    }
    }


    GET /test_index/_search
    {
    "query": {
    "bool": {
    "must": { "match": { "name": "tom" }},
    "should": [
    { "match": { "hired": true }},
    { "bool": {
    "must": { "match": { "personality": "good" }},
    "must_not": { "match": { "rude": true }}
    }}
    ],
    "minimum_should_match": 1
    }
    }
    }


    三.filter与query对比
    1、filter与query示例


    PUT /company/employee/2
    {
    "address": {
    "country": "china",
    "province": "jiangsu",
    "city": "nanjing"
    },
    "name": "tom",
    "age": 30,
    "join_date": "2016-01-01"
    }

    PUT /company/employee/3
    {
    "address": {
    "country": "china",
    "province": "shanxi",
    "city": "xian"
    },
    "name": "marry",
    "age": 35,
    "join_date": "2015-01-01"
    }


    搜索请求:年龄必须大于等于30,同时join_date必须是2016-01-01


    GET /company/employee/_search
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "join_date": "2016-01-01"
    }
    }
    ],
    "filter": {
    "range": {
    "age": {
    "gte": 30
    }
    }
    }
    }
    }
    }


    2、filter与query对比大解密

    filter,仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响
    query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序

    一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query;如果你只是要根据一些条件筛选出一部分数据,不关注其排序,那么用filter
    除非是你的这些搜索条件,你希望越符合这些搜索条件的document越排在前面返回,那么这些搜索条件要放在query中;如果你不希望一些搜索条件来影响你的document排序,那么就放在filter中即可

    3、filter与query性能

    filter,不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据
    query,相反,要计算相关度分数,按照分数进行排序,而且无法cache结果

     

    四.组合查询 

    1、match all


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


    2、match


    GET /_search
    {
    "query": { "match": { "title": "my elasticsearch article" }}
    }


    3、multi match


    GET /test_index/test_type/_search
    {
    "query": {
    "multi_match": {
    "query": "test",
    "fields": ["test_field", "test_field1"]
    }
    }
    }


    4、range query


    GET /company/employee/_search
    {
    "query": {
    "range": {
    "age": {
    "gte": 30
    }
    }
    }
    }


    5、term query


    GET /test_index/test_type/_search
    {
    "query": {
    "term": {
    "test_field": "test hello"
    }
    }
    }


    6、terms query


    GET /_search
    {
    "query": { "terms": { "tag": [ "search", "full_text", "nosql" ] }}
    }


    7、exist query(2.x中的查询,现在已经不提供了)


    GET /website/article/_search
    {
    "query": {
    "bool": {
    "must": [
    {
    "match": {
    "title": "elasticsearch"
    }
    }
    ],
    "should": [
    {
    "match": {
    "content": "elasticsearch"
    }
    }
    ],
    "must_not": [
    {
    "match": {
    "author_id": 111
    }
    }
    ]
    }
    }
    }

    {

    "bool": {
    "must": { "match": { "title": "how to make millions" }},
    "must_not": { "match": { "tag": "spam" }},
    "should": [
    { "match": { "tag": "starred" }}
    ],
    "filter": {
    "range": { "date": { "gte": "2014-01-01" }}
    }
    }
    }

    bool
    must,must_not,should,filter

    每个子查询都会计算一个document针对它的相关度分数,然后bool综合所有分数,合并为一个分数,当然filter是不会计算分数的

    {
    "bool": {
    "must": { "match": { "title": "how to make millions" }},
    "must_not": { "match": { "tag": "spam" }},
    "should": [
    { "match": { "tag": "starred" }}
    ],
    "filter": {
    "bool": {
    "must": [
    { "range": { "date": { "gte": "2014-01-01" }}},
    { "range": { "price": { "lte": 29.99 }}}
    ],
    "must_not": [
    { "term": { "category": "ebooks" }}
    ]
    }
    }
    }
    }

    GET /company/employee/_search
    {
    "query": {
    "constant_score": {
    "filter": {
    "range": {
    "age": {
    "gte": 30
    }
    }
    }
    }
    }
    }

    六.定位不合法的搜索


    GET /test_index/test_type/_validate/query?explain
    {
    "query": {
    "math": {
    "test_field": "test"
    }
    }
    }


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

    GET /test_index/test_type/_validate/query?explain
    {
    "query": {
    "match": {
    "test_field": "test"
    }
    }
    }

    {
    "valid": true,
    "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
    },
    "explanations": [
    {
    "index": "test_index",
    "valid": true,
    "explanation": "+test_field:test #(#_type:test_type)"
    }
    ]
    }

    一般用在那种特别复杂庞大的搜索下,比如你一下子写了上百行的搜索,这个时候可以先用validate api去验证一下,搜索是否合法

     

     

     

  • 相关阅读:
    4、配置解决中文乱码的过滤器
    3、请求参数绑定
    2、SpringMVC常用注解
    SpringMVC快速搭建
    深拷贝与浅拷贝笔记
    SpringBoot入门(三)——SpringData JPA
    SpringBoot入门(二)——Web
    SpringBoot入门(一)——HelloWorld、配置、日志
    Java SSM(十八)——Mybatis查缺补漏
    Java SSM(十七)——SpringMVC查缺补漏
  • 原文地址:https://www.cnblogs.com/Transkai/p/11279048.html
Copyright © 2011-2022 走看看