技术交流28群

服务热线

135-6963-3175

微信服务号

Elasticsearch查询 更新时间 2020-3-10 浏览1574次

索引相当于数据库服务器的一个数据库,索引类型相当于数据库的一张表,而文档相当于一行数据。

概要

查询包含query和bool query查询

query包含match,match_phrase,term,terms,multi_match

bool query包含should,must,must_not

范围用range,exists

排序用sort

指定字段_source

分页:from size

match 

会条件分词去索引里面找 命中一个满足就返回,match模糊匹配,先对输入进行分词,对分词后的结果进行查询,文档只要包含match查询条件的一部分就会被返回。

{
  "query": {
    "match": {
      "content": {
        "query": "里皮恒大",
        "operator": "and"
      }
    }
  }
}

operator默认是or,也就是说,“里皮恒大”被分词为“里皮”和“恒大”,只要content中出现两个之一,都会搜索到;设置为and之后,只有同时出现都会被搜索到。

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

match_phrase 

必须包含一模一样的串,才会返回(包含短语的意思)

文档同时满足下面两个条件才会被搜索到:

(1)分词后所有词项都要出现在该字段中

(2)字段中的词项顺序要一致

{
  "query": {
     "match_phrase": {
        "content": "里皮恒大"
      }
   }
}


词项查询

词项搜索时对倒排索引中存储的词项进行精确匹配,词项级别的查询通过用于结构化数据,如数字、日期和枚举类型。

term

term结构化字段查询,匹配一个值,且输入的值不会被分词器分词。

在查询的字段只有一个值的时候,应该使用term而不是terms,在查询字段包含多个的时候才使用terms(类似于sql中的in、or),使用terms语法,JSON中必须包含数组。

GET /test_index/test_type/_search
 {
   "term":{
    "lang":1
    }
}
{
    "query": {
     "term": {
         "postdate": "2015-12-10 00:41:00"
     }
  }
}


terms

term的升级版,如上面查询的postdate字段,可以设置多个。

GET /_search
{
  "query": {
  "terms": {
      "postdate": [
          "2015-12-10 00:41:00",
          "2016-02-01 01:39:00"
      ]
    }
    }
}

因为term是精确匹配,所以不要问,[]中的关系怎么设置and?这怎么可能,既然是精确匹配,一个字段也不可能有两个不同的值。

{
                    "terms":{
                        "domain":[
                            "dailymasala.co",
                            "goldenmob.com"
                        ]
                    }
}

multi_match

如果我们希望两个字段进行匹配,其中一个字段有这个文档就满足的话,使用multi_match

{
  "query": {
    "multi_match": {
        "query" : "我的宝马多少马力",
        "fields" : ["title", "content"]
    }
  }
}
GET /test_index/test_type/_search
{
  "query": {
    "multi_match": {
      "query": "test",
      "fields": ["test_field", "test_field1"]
    }
  }
}


query 和 filter

两者都可以写查询条件,而且语法也类似。区别在于,query 上下文的条件是用来给文档打分的,匹配越好 _score 越高;filter 的条件只产生两种结果:符合与不符合,后者被过滤掉,filter用于塞选结果集。


range query

匹配某一范围内的数据型、日期类型或者字符串型字段的文档,注意只能查询一个字段,不能作用在多个字段上。

GET /company/employee/_search

数值:

{
  "query": {
  "range": {
   "reply": {
        "gte": 245,
        "lte": 250
      }
    }
 }
}

支持的操作符如下:

gt:大于,gte:大于等于,lt:小于,lte:小于等于

日期:

{
  "query": {
  "range": {
     "postdate": {
         "gte": "2016-09-01 00:00:00",
         "lte": "2016-09-30 23:59:59",
        "format": "yyyy-MM-dd HH:mm:ss"
     }
  }
 }
}

format不加也行,如果写的时间格式正确。

exists query

返回对应字段中至少有一个非空值的文档,也就是说,该字段有值(待会会说明这个概念)。

{
  "query": {
    "exists": {
      "field": "user"
    }
  }
}

ids query

查询具有指定id的文档。

{
  "query": {
    "ids": {
      "type": "news",
      "values": "2101"
    }
  }
}

类型是可选的,也可以以数据的方式指定多个id。

{
  "query": {
    "ids": {
      "values": [
        "2101",
        "2301"
      ]
    }
  }
}


bool query查询

should: 满足其中一个条件就行,会带一个以上的条件,至少满足一个条件,这个文档就符合should

curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}'

must: 必须满足所有条件,文档必须完全匹配条件

must_not: 返回不满足当前筛选添加的结果集,文档必须不匹配条件

{
  "query": {
    "bool": {
      "must": {
        "term": {
          "content": "宝马"
        }
      },
      "must_not": {
        "term": {
          "tags": "宝马"
        }
      }
    }
  }
}

filter:筛选结果集

curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'

{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

分页(以term为例)

GET index/type/_search
{
    "from":0,
    "size":100,
    "query":{
        "term":{
            "area":"GuangZhou"
        }
    }
}

包含指定字段(以term为例)

GET index/type/_search
{
    "_source":["hobby", "name"],
    "query":{
        "term":{
            "area":"GuangZhou"
        }
    }
}


排序(以term为例)

单个字段排序:

GET index/type/_search
{
    "query":{
        "term":{
            "area":"GuangZhou"
        }
    },
    "sort":[
        {"user_id":{"order":"asc"}},
        {"salary":{"order":"desc"}}
    ]
}