elasticsearch-search


Elasticsearch-search知识点。

Elasticsearch-search知识点

search结果分析

GET _search

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 21,
    "successful": 21,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": ".kibana",
        "_type": "config",
        "_id": "5.2.0",
        "_score": 1,
        "_source": {
          "buildNum": 14695
        }
      }
    ]
  }
}

took:整个搜索请求花费了1毫秒

hits.total:本次搜索,返回了1条结果(es官方默认限制索引查询最多只能查询10000条数据)

hits.max_score:本次搜索的所有结果中,最大的相关度分数是多少

hits.hits:默认查询前10条数据,完整数据,按_score降序排序

shards:这次查询路由到的primary shard和replica shard

timeout:默认无timeout,可以手动指定timeout,走timeout查询执行机制

search的timeout机制

有些搜索应用对时间是很敏感的,比如说我们的电商网站,你不能说让用户等10分钟,才能等到一次搜索请求的结果,如果那样的话人家早走了,不来买东西了。

而timeout机制,就是指定每个shard只能在timeout时间范围内将搜索到的部分数据(也可能全都搜索到了)直接返回给client,而不是等所有的数据全部搜索出来以后再返回。

比如,有2个shard,每个shard要搜索出来1000条数据需要1分钟,此时我们指定timeout=10ms,每个shard运行到10ms的时候可能就搜索出10条,那么这个请求本来应该在1分钟后总共拿到2000条数据,但是指定timeout后,就会在10ms拿到20条数据返回给客户端。

这样就可以确保一次搜索请求可以在指定的timeout时长内完成。为一些时间敏感的搜索应用提供良好的支持。

timeout的语法:

GET /_search?timeout=10m

timeout的单位:ms(毫秒),s(秒),m(分钟)

multi-index&multi-type搜索模式

(1) /_search:所有索引,所有type下的所有数据都搜索出来
(2) /index1/_search:指定一个index,搜索其下所有type的数据
(3) /index1,index2/_search:同时搜索两个index下的数据
(4) /*1,*2/_search:按照通配符去匹配多个索引
(5) /index1/type1/_search:搜索一个index下指定的type的数据
(6) /index1/type1,type2/_search:可以搜索一个index下多个type的数据
(7) /index1,index2/type1,type2/_search:搜索多个index下的多个type的数据
(8) /_all/type1,type2/_search:_all,可以代表搜索所有index下的指定type的数据

备注:中间不要带空格

GET /rrc,rrs/index1,user/_search

{
  "error": {
    "root_cause": [
      {
        "type": "index_not_found_exception",
        "reason": "no such index",
        "resource.type": "index_or_alias",
        "resource.id": "rrs",
        "index_uuid": "_na_",
        "index": "rrs"
      }
    ],
    "type": "index_not_found_exception",
    "reason": "no such index",
    "resource.type": "index_or_alias",
    "resource.id": "rrs",
    "index_uuid": "_na_",
    "index": "rrs"
  },
  "status": 404
}

# ?怎么和老师讲的有点出入,百度中:https://stackoverflow.com/questions/45461096/elasticsearch-returns-404-while-multi-index-multi-type-search
GET /rrc,index2/user,type2/_search?ignore_unavailable

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "rrc",
        "_type": "user",
        "_id": "9",
        "_score": 1,
        "_source": {
          "name": "tiedan",
          "price": 1764
        }
      }
    ]
  }
}

ES分页

GET _search
"hits": {
    "total": 17,
    "max_score": 1
}

# 作分页查询
GET _search?from=0&size=1
    
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 21,
    "successful": 21,
    "failed": 0
  },
  "hits": {
    "total": 17,
    "max_score": 1,
    "hits": [
      {
        "_index": ".kibana",
        "_type": "config",
        "_id": "5.2.0",
        "_score": 1,
        "_source": {
          "buildNum": 14695
        }
      }
    ]
  }
}

关注深度分页问题,是一个归并排序的过程。

query string基础语法

q=field:search content的语法,还有一个是掌握+和-的含义

GET /test_index/test_type/_search?q=test_field:test12

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "test_index",
        "_type": "test_type",
        "_id": "12",
        "_score": 0.2876821,
        "_source": {
          "test_field": "test12"
        }
      }
    ]
  }
}


GET /test_index/test_type/_search?q=+test_field:test12

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "test_index",
        "_type": "test_type",
        "_id": "12",
        "_score": 0.2876821,
        "_source": {
          "test_field": "test12"
        }
      }
    ]
  }
}

GET /test_index/test_type/_search?q=-test_field:test12
    
    
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "test_index",
        "_type": "test_type",
        "_id": "2",
        "_score": 1,
        "_source": {
          "test_field": "replaced test2"
        }
      }
    ]
  }
}

_all metadata的原理和作用

GET /test_index/test_type/_search?q=test

直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来。我们在进行中搜索的时候,难道是对document中的每一个field都进行一次搜索吗?不是的

es中的_all元数据,在建立索引的时候,我们插入一条document,它里面包含了多个field,此时,es会自动将多个field的值,全部用字符串的方式串联起来,变成一个长的字符串,作为_all field的值,同时建立索引

后面如果在搜索的时候,没有对某个field指定搜索,就默认搜索_all field,其中是包含了所有field的值的

举个例子

{
  "name": "jack",
  "age": 26,
  "email": "jack@sina.com",
  "address": "guamgzhou"
}

"jack 26 jack@sina.com guangzhou",作为这一条document的_all field的值,同时进行分词后建立对应的倒排索引

生产环境不使用

mapping

准备数据:

PUT /website/article/1
{
  "post_date": "2017-01-01",
  "title": "my first article",
  "content": "this is my first article in this website",
  "author_id": 11400
}

PUT /website/article/2
{
  "post_date": "2017-01-02",
  "title": "my second article",
  "content": "this is my second article in this website",
  "author_id": 11400
}

PUT /website/article/3
{
  "post_date": "2017-01-03",
  "title": "my third article",
  "content": "this is my third article in this website",
  "author_id": 11400
}

尝试各种搜索

GET /website/article/_search?q=2017 3条结果
GET /website/article/_search?q=2017-01-01 3条结果
GET /website/article/_search?q=post_date:2017-01-01 1条结果
GET /website/article/_search?q=post_date:2017 1条结果

在上面的准备数据过程中,ES使用dynamic mapping,自动为我们建立index,创建type,以及type对应的mapping,mapping中包含了每个field对应的数据类型,以及如何分词等设置
我们当然,后面会讲解,也可以手动在创建数据之前,先创建index和type,以及type对应的mapping

GET /website/_mapping/article
    
{
  "website": {
    "mappings": {
      "article": {
        "properties": {
          "author_id": {
            "type": "long"
          },
          "content": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "post_date": {
            "type": "date"
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

搜索结果为什么不一致,因为es自动建立mapping的时候,设置了不同的field不同的data type。不同的data type的分词、搜索等行为是不一样的。所以出现了_all field和post_date field的搜索表现完全不一样。


文章作者: WangQingLei
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WangQingLei !
  目录