本节应该属于上大节的最后一个小结,但是因为其重要性因此单独起一节。ES提供了一种非常灵活又富有表现力的查询语言,采用JSON接口的方式实现丰富的查询,并使你的查询语句更灵活、更精确、更易读且易调试,这种方式被称为Query DSL语言。其查用如下的格式就进行查询,可以指定from和size进行分页查询

GET /_search
{
    "query": YOUR_QUERY_HERE
}
  • match_all 即无检索条件获取全部数据

    # 查询全部数据
    GET /boss/_search
    {
        "query": {
          "match_all": {}
        }
    }
    
  • query_string 查询 可以执行一些复杂的查询

    GET /boss/_search
    {
        "query" : {
            "query_string": {
                //查询inter=QHAI_UNHQ_BalanceInfoQuery 或者reqinfo.SERIAL_NUMBER = 151的记录
              "query": "inter:QHAI_UNHQ_BalanceInfoQuery or reqinfo.SERIAL_NUMBER:151"
            }
        }
    }
    
  • match 普通检索,很多文章都说match查询会对查询内容进行分词,其实并不完全正确,match查询也要看检索的字段type类型,如果字段类型本身就是不分词的keyword(not_analyzed),那match就等同于term查询了

    GET /boss/_search
    {
        "query": {
            "match": {
                "title": "我们会被分词"
            }
        }
    }
    
  • multi_match对多个字段进行检索,比如我想查询titlecontent中有我们关键词的文档

    GET /boss/_search
    {
        "query": {
          "multi_match": {
            "query": "15110990584",
            "fields": ["reqinfo.SERIAL_NUMBER","reqinfo.SERIAL_NUMBER.keyword"]
          }
        }
    }
    
  • match_phrase/match_phrase_prefix 短查询 slop为几就是允许间隔几个词,几个词之间离的越近分数越高

    GET /boss/_search
    {
        "query": {
          "match_phrase_prefix" : {
                "reqinfo.SERIAL_NUMBER": {
                    "query" : "151109905",
                    "max_expansions" : 10
                }
            }
        },
        "size": 50
    }
    
  • term查找被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串。

    GET /boss/_search
    {
        "query": {
          "term": {
            "reqinfo.SERIAL_NUMBER": {
              "value": "15110990584"
            }
          }
        }
    }
    
  • terms 查询和 term查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件。terms 查询对于输入的文本不分析。它查询那些精确匹配的值(包括在大小写、重音、空格等方面的差异)

    GET /boss/_search
    {
        "query": {
          "terms": {
            "reqinfo.SERIAL_NUMBER": [
              "151xxxxxxxx",
              "152xxxxxxxx"
            ]
          }
          
        }
    }
    
  • range范围查找,如果对字符串进行比较,那么是数字<大写字母<小写字母,字符从头开始比较,和js一样range的主要参数为:

    `gt`: `>` 大于(greater than)
    `lt`: `<` 小于(less than)
    `gte`: `>=` 大于或等于(greater than or equal to)
    `lte`: `<=` 小于或等于(less than or equal to)
    GET /boss/_search
    {
        "query" : {
            "range": {
              "requesttime": {
                "gt":"20190103101058526",
                "lt":"20190103101158526"
              }
            }
        }
    }
    
  • wildcard shell通配符查询: ? 一个字符 * 多个字符,查询倒排索引中符合pattern的关键词

    GET /my_index/address/_search
    {
        "query": {
            "wildcard": {
                "postcode": "W?F*HW" 
            }
        }
    }
    
  • prefix 前缀查询

  • regexp 正则查询

    GET /my_index/address/_search
    {
        "query": {
            "regexp": {
                "postcode": "W[0-9].+" 
            }
        }
    }
    
  • bool 布尔连接查询must必须全部满足、must_not 必须全部不满足、should满足一个即可

    GET /boss/_search
    {
        "query" : {
            "bool": {
              "filter": [{
                "term": {
                  "reqinfo.SERIAL_NUMBER": "15110990584"
                }
              },{
                  "term": {
                  "reqinfo.ACCT_TYPE_CODE": "0"
                }
              }],
              "must": [
                {"term": {
                  "response.respCode": "0"
                }}
              ]
            }
        }
    }
    
  • filter查询 通常情况下会配合match之类的使用,对符合查询条件的数据进行过滤。

  • exists和missing查询,分别用来判断是否存在或者缺失

  • constant_score查询:它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下。可以使用它来取代只有 filter 语句的 bool 查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助。

  • 设置最小匹配度  后面可以是数字也可以是百分比

    GET /my_index/my_type/_search
    {
      "query": {
        "match": {
          "title": {
            "query":                "quick brown dog",
            "minimum_should_match": "75%"
          }
        }
      }
    }
    
  • 使用临近度提高相关度

    GET /my_index/my_type/_search
    {
      "query": {
        "bool": {
          "must": {
            "match": { 
              "title": {
                "query":                "quick brown fox",
                "minimum_should_match": "30%"
              }
            }
          },
          "should": {
            "match_phrase": { 
              "title": {
                "query": "quick brown fox",
                "slop":  50
              }
            }
          }
        }
      }
    }
    

SQL查询

ES6.x中开始通过xpack的方式提供了SQL检索方式,避免DSL语言的学习成本。当然如果要在在程序中以JDBC的方式连接的需要白金会员的key才行。当对于交互式或者SQL转DSL的方式可以免费的使用。

### 直接使用SQL的方式进行检索
POST /_xpack/sql?format=txt
{
    "query": "select inter,(responsetime -requesttime ) request_time  from boss order by request_time desc"
}

### 将SQL转换成DSL进行查询
POST /_xpack/sql/translate
{
    "query": "select inter,(responsetime -requesttime ) request_time  from boss order by request_time desc"
}
//返回
{
  "size" : 1000,
  "_source" : {
    "includes" : [
      "inter"
    ],
    "excludes" : [ ]
  },
  "docvalue_fields" : [
    {
      "field" : "responsetime",
      "format" : "use_field_mapping"
    },
    {
      "field" : "requesttime",
      "format" : "use_field_mapping"
    }
  ],
  "sort" : [
    {
      "_script" : {
        "script" : {
          "source" : "InternalSqlScriptUtils.nullSafeSortNumeric(InternalSqlScriptUtils.sub(InternalSqlScriptUtils.docValue(doc,params.v0),InternalSqlScriptUtils.docValue(doc,params.v1)))",
          "lang" : "painless",
          "params" : {
            "v0" : "responsetime",
            "v1" : "requesttime"
          }
        },
        "type" : "number",
        "order" : "desc"
      }
    }
  ]
}

排序

在 Elasticsearch 中, 相关性得分 由一个浮点数进行表示,并在搜索结果中通过 _score 参数返回,默认排序是 _score 降序。有时,相关性评分对你来说并没有意义,而是需要自定义排序,这个时候可以使用sort进行之自定义排序

{
    "query" : {
        "bool" : {
            "filter" : { "term" : { "user_id" : 1 }}
        }
    },
    //按照时间排序
    "sort": { "date": { "order": "desc" }}
}
# 多字段排序
{
    "query" : {
        "bool" : {
            "must":   { "match": { "tweet": "manage text search" }},
            "filter" : { "term" : { "user_id" : 2 }}
        }
    },
    "sort": [
        { "date":   { "order": "desc" }},
        { "_score": { "order": "desc" }}
    ]
}