全文检索 Elasticsearch-进阶检索[新人创作礼]

93 阅读3分钟

二、进阶检索

1、导入批量数据

{
    "account_number": 1,
    "balance": 39225,
    "firstname": "Amber",
    "lastname": "Duke",
    "age": 32,
    "gender": "M",
    "address": "880 Holmes Lane",
    "employer": "Pyrami",
    "email": "amberduke@pyrami.com",
    "city": "Brogan",
    "state": "IL"
}

官方准备的示例:github.com/elastic/ela…

segmentfault.com/a/119000003…

在Kibana中导入批量数据: file

POST /bank/account/_bulk
{"index":{"_id":"1"}}
{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
...

2、SearchAPI#

ES 支持两种基本方式检索:

  • 一个是通过使用 REST request URI 发送搜索参数(uri+检索参数)
  • 另一个是通过使用 REST request body 来发送它们(uri+请求体)

3、返回结构#

{
  "took": 20,   // 整个搜索请求花费的毫秒数
  "timed_out": false, // 查询超时与否,false没有超时, true为超时
  "_shards": {
    "total": 5,  // 分片数量
    "successful": 5, // 成功的分片数量,即是没有故障的分片
    "failed": 0  // 失败的分片数量,即是出现故障的分片
  },
  "hits": {
    "total": 100000,  // 查询整个索引的文档数量
    "max_score": 1,  // 所有文档匹配查询中_score的最大值
    "hits": [
      {
        "_index": "test_index",  // 索引名称
        "_type": "test_index",   // 索引类型
        "_id": "030180142347",    // 文档id
        "_score": 1,   // 这条文档与查询的条件匹配程度
        "_source": {   // 文档的json数据
          "name": "lodge", 
          "age": 25
        }
      }
    ]
  }
}

4、查询方式#

1、GET查询方式#

// 在所有索引的所有类型中搜索
GET /_search
​
// 在索引test_index的所有类型中搜索
GET /test_index/_search
​
// 在索引test_index和test_index1的所有类型中搜索
// 多个索引查询
GET /test_index,test_index1/_search
​
// 在索引以test开头的所有类型中搜索
// 正则查询
GET /test_*/_search
​
// 在所有索引的user和tweet的类型中搜索
GET /_all/user,tweet/_search
​
// 条件查询文档
GET /test_index/_search?q=字段名:对应的值
​
// 分页查询,size代表结果数量,from代表跳过开始的结果数
// size相当sql的limit,from相当sqloffset
GET /test_index/_search?size=5&from=10

示例:

GET bank/_search?q=*&sort=account_number:desc

2、POST 查询方式(请求体查询方式)#

// 请求体基本结构
{
  "query": {},   // 相当sqlwhere条件
  "sort": {},    // 相当sqlorder by排序
  "from":0,      // 相当sqloffset从第几行获取
  "size":20,     // 相当sql的limit返回数据量
  "_source": []  // 获取那些文档字段数据
}

query内部简单包含关系的示意图 file

请求示例:

POST /bank/_search
{
  "query": {
    "match_all": {}
  },
  "sort":[
    {
      "account_number": "asc"
    },
    {
      "balance": "desc"
    }
  ]
}

ES把这种可以通过执行查询的 Json 风格的 DSLdomain-specific-language 领域特定语言),被称为 Query DSL

3、精度控制搜索#

1、针对analyzed字段进行精确查询

POST /test_index/_search
{
    "query": {
        "match": {
           "title": {
               "query":  "人生苦短,我用python",
               "minimum_should_match":"100%"  // 精确匹配,需要指定匹配相似度
            }
        }
    }
}

match用法:

GET bank/_search
{
  "query":{
    "match": {
      "address": "Kings"
    }
  }
}

term用法: 和match 一样,匹配某个属性的值。全文检索字段用 match,其他非 text 字段匹配用 term。

全文检索按照评分进行排序,会对检索条件进行分词匹配。

4、 复杂查询#

DSL:Domain Specific Language,ES提供一种基于JSON的查询语言,这种查询语言包含两种子句模式:

  • 1.Leaf query clauses
  • 2.Compound query clauses --常用的就是bool组合查询

Query一般来说包含两各部分:query context 或 filter context: 示例:

GET /_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title":   "Search"        }},
        { "match": { "content": "Elasticsearch" }} 
      ],
      "filter": [
        { "term":  { "status": "published" }},
        { "range": { "publish_date": { "gte": "2015-01-01" }}}
      ]
    }
  }
}

这个例子的query就包含了所有2种context,并使用了bool组合查询,可以看到bool是最外围的关键字,must与filter并行。 bool组合查询的子关键字主要包含must,must_not,should,分别对应AND、NOT、OR三种逻辑运算,此外还有一个filter子关键字。 --filter与must:match的区别: 参考:www.elastic.co/guide/en/el…

1.must:match会为匹配到的每个记录打分,称作scoring,表示匹配程度,查询的结果按打分进行排序。 2.filter与must:match基本一致,唯一的区别是其结果不参与打分,相当于一个再过滤。