ElasticSearch搜索介绍四

ElasticSearch搜索html

 

最基础的搜索:java

curl -XGET http://localhost:9200/_search

返回的结果为:数据库

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 16,
    "successful": 16,
    "failed": 0
  },
  "hits": {
    "total": 13,
    "max_score": 1,
    "hits": [
      {
        "_index": ".kibana",
        "_type": "config",
        "_id": "5.5.1",
        "_score": 1,
        "_source": {
          "buildNum": 15405
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "8",
        "_score": 1,
        "_source": {
          "name": "deda",
          "age": 31,
          "job": "stu"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "30",
        "_score": 1,
        "_source": {
          "name": "tomi",
          "age": 19,
          "job": "master"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "5",
        "_score": 1,
        "_source": {
          "name": "ming",
          "age": 33,
          "job": "coding",
          "like": "football",
          "tel": "122334"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "2",
        "_score": 1,
        "_source": {
          "name": "fukk",
          "age": 30,
          "job": "stu"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "4",
        "_score": 1,
        "_source": {
          "name": "mask",
          "age": 40,
          "job": "CEO"
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "6",
        "_score": 1,
        "_source": {
          "name": "nan",
          "age": 25,
          "job": "coding"
        }
      },
      {
        "_index": "peoples",
        "_type": "employee",
        "_id": "2",
        "_score": 1,
        "_source": {
          "first_name": "Jane",
          "last_name": "Smith",
          "age": 32,
          "about": "I like to collect rock albums",
          "interests": [
            "music"
          ]
        }
      },
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "1",
        "_score": 1,
        "_source": {
          "first_name": "John",
          "last_name": "Smith",
          "age": 25,
          "about": "I love to go rock climbing",
          "interests": [
            "sports",
            "music"
          ]
        }
      },
      {
        "_index": "people",
        "_type": "man",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "ahaii",
          "age": 27,
          "job": "coding"
        }
      }
    ]
  }
}
View Code

索引全部文档,返回结果中默认显示前十条数据。数组

hits:缓存

返回结果中最重要的部分是 hits ,它 包含 total 字段来表示匹配到的文档总数,而且一个 hits 数组包含所查询结果的前十个文档。app

在 hits 数组中每一个结果包含文档的 _index 、 _type 、 _id ,加上 _source 字段。这意味着咱们能够直接从返回的搜索结果中使用整个文档。这不像其余的搜索引擎,仅仅返回文档的ID,须要你单独去获取文档。curl

每一个结果还有一个 _score ,它衡量了文档与查询的匹配程度。默认状况下,首先返回最相关的文档结果,就是说,返回的文档是按照 _score 降序排列的。在这个例子中,咱们没有指定任何查询,故全部的文档具备相同的相关性,所以对全部的结果而言 1 是中性的 _score 。elasticsearch

took:ide

took 值表示执行整个搜索请求耗费了多少毫秒。测试

shards:

_shards 部分告诉咱们在查询中参与分片的总数,以及这些分片成功了多少个失败了多少个。正常状况下咱们不但愿分片失败,可是分片失败是可能发生的。若是咱们遭遇到一种灾难级别的故障,在这个故障中丢失了相同分片的原始数据和副本,那么对这个分片将没有可用副原本对搜索请求做出响应。倘若这样,Elasticsearch 将报告这个分片是失败的,可是会继续返回剩余分片的结果。

不一样索引、不一样类型的搜索:

/_search在全部的索引中搜索全部的类型

/gb/_search在 gb 索引中搜索全部的类型

/gb,us/_search在 gb 和 us 索引中搜索全部的文档

/g*,u*/_search在任何以 g 或者 u 开头的索引中搜索全部的类型

/gb/user/_search在 gb 索引中搜索 user 类型

/gb,us/user,tweet/_search在 gb 和 us 索引中搜索 user 和 tweet 类型

/_all/user,tweet/_search在全部的索引中搜索 user 和 tweet 类型

当在单一的索引下进行搜索的时候,Elasticsearch 转发请求到索引的每一个分片中,能够是主分片也能够是副本分片,而后从每一个分片中收集结果。多索引搜索刚好也是用相同的方式工做的--只是会涉及到更多的分片。

搜索一个索引有五个主分片和搜索五个索引各有一个分片准确来所说是等价的。

 

搜索结果分页:

和 SQL 使用 LIMIT 关键字返回单个 page 结果的方法相同,Elasticsearch 接受 from 和 size 参数:

size
显示应该返回的结果数量,默认是  10
from
显示应该跳过的初始结果数量,默认是  0

 显示3条搜索结果:

curl -XGET http://localhost:9200/_search?size=3

显示第4-6条搜索结果:

curl -XGET http://localhost:9200/_search?size=3&from=3

显示第7-9条搜索结果:

curl -XGET http://localhost:9200/_search?size=3&from=6

 

ElasticSearh搜索API的形式:

一、在查询字符串中传递参数

查询man类型(表)中全部name字段为ahaii的文档:

curl -XGET http://localhost:9200/_all/man/_search?q=name:ahaii

搜索结果以下:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 16,
    "successful": 16,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.6931472,
    "hits": [
      {
        "_index": "people",
        "_type": "man",
        "_id": "1",
        "_score": 0.6931472,
        "_source": {
          "name": "ahaii",
          "age": 27,
          "job": "coding"
        }
      }
    ]
  }
}

 

二、使用请求体查询

使用请求体查询时,如ElasticSearch系列第一片中介绍。

 

若是查询多个不一样的字段,Elasticsearch 取出全部字段的值拼接成一个大的字符串,做为 _all 字段进行索引。

例如,在索引一个包含以下字段的文档时:

{
    "name":    "tim",
    "job":     "CEO",
    "age":     "25"
}

这就好似增长了一个名叫 _all 的额外字段,来检索下面这个字符串:

tim CEO 25

除非设置特定字段,不然查询字符串就使用 _all 字段进行搜索。

 

ElasticSearch中将数据分为两类,精确值(词条 term)全文

精确值很容易查询。结果是二进制的:要么匹配查询,要么不匹配。这种数据的查询方式很想关系型数据库中的SQL语句。

精确值查询须要彻底匹配,即字符的大小写,字符的数量和位置都是相同的,词条(term)查询使用字符的彻底匹配方式进行文本搜索,词条查询不会分析(analyze)查询字符串,给定的字段必须彻底匹配词条查询中指定的字符串。因为词条查询的字符串是未经分析(analyzed)的词条,所以,词条查询常常用于结构化的数据,例如,数值,日期等,

全文查询数据要微妙的多。咱们问的不仅是“这个文档匹配查询吗”,而是“该文档匹配查询的程度有多大?”换句话说,该文档与给定查询的相关性如何?

为了促进这类在全文域中的查询,Elasticsearch 首先分析文档,以后根据结果建立倒排索引 。

倒排索引:

阅读这片博文:http://blog.csdn.net/hguisu/article/details/7962350

为了获取到等多的相关文档,在分词的时候,还须要对单词作一些其余操做。若是咱们将词条规范为标准模式,那么咱们能够找到与用户搜索的词条不彻底一致,但具备足够相关性的文档,好比:

一、忽略关键词的大小写

二、忽略关键词的单复数形式

三、模糊匹配词意相同或相近

 

单词分析与过滤

ElasticSearch中,分词和标准化的过程就是分析的过程。

分析包含如下两个过程:

一、将一块文本分红适合于倒排索引的独立的词条

二、将这些词条统一化为标准格式以提升它们的“可搜索性”

以上工做由分析器完成。分析器其实是由三个功能组成:

一、字符串过滤器:

首先,字符串按顺序经过每一个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器能够用来去掉HTML,或者将 & 转化成 `and`。

二、分词器:

其次,字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分红词条。

三、Token过滤器:

最后,词条按顺序经过每一个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick ),删除词条(例如, 像 a`, `and`, `the 等无用词),或者增长词条(例如,像 jump 和 leap 这种同义词)。

 

ElasticSearch内置分析器种类:

每种分析器对字符串的处理方式不一样,以语句"Set the shape to semi-transparent by calling set_trans(5)"为例:

一、标准分词器:

标准分析器是Elasticsearch默认使用的分析器。它是分析各类语言文本最经常使用的选择。它根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写。它会产生:

set, the, shape, to, semi, transparent, by, calling, set_trans, 5

二、简单分析器:

简单分析器在任何不是字母的地方分隔文本,将词条小写。它会产生:

set, the, shape, to, semi, transparent, by, calling, set, trans

三、空格分析器:

空格分析器在空格的地方划分文本。它会产生:

Set, the, shape, to, semi-transparent, by, calling, set_trans(5)

四、语言分析器:

特定语言分析器可用于不少语言。它们能够考虑指定语言的特色。例如, 英语 分析器附带了一组英语无用词(经常使用单词,例如 and 或者 the ,它们对相关性没有多少影响),它们会被删除。 因为理解英语语法的规则,这个分词器能够提取英语单词的词干 。

英语分词器会产生下面的词条:

set, shape, semi, transpar, call, set_tran, 5

注意,transparent、 calling 和 set_trans 已经变为词根格式。

当全文查询时,es会对查询字符串作一样的分析处理,以保证搜索的词条格式与索引中的词条格式保持一致。

当精确查询时,es不会分析查询字符串,而是查询匹配到的精确值。

 

测试分析器:

为了理解es内部是分词的过程,可使用 analyze API 测试分析器来看文本是如何被分析的。在消息体里,指定分析器和要分析的文本:

curl -XGET http://localhost:9200/_analyze
{
  "analyzer": "standard",
  "text": "hello this is my blog."
}

能够获得如下结果:

{
  "tokens": [
    {
      "token": "hello",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "this",
      "start_offset": 6,
      "end_offset": 10,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "is",
      "start_offset": 11,
      "end_offset": 13,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "my",
      "start_offset": 14,
      "end_offset": 16,
      "type": "<ALPHANUM>",
      "position": 3
    },
    {
      "token": "blog",
      "start_offset": 17,
      "end_offset": 21,
      "type": "<ALPHANUM>",
      "position": 4
    }
  ]
}
View Code

结果中,token是实际存储到索引中的词条,position 指明词条在原始文本中出现的位置。 start_offset 和 end_offset 指明字符在原始字符串中的位置。

 

映射

为了可以将时间域视为时间,数字域视为数字,字符串域视为全文或精确值字符串, Elasticsearch 须要知道每一个域中数据的类型。这个信息包含在映射中。

ElasticSearch中核心域类型:

一、字符串:string

二、整型:byte,short,long,integer

三、浮点:float,double

四、布尔:boolean

五、日期:date

 

自定义映射:

域里最重要的属性是type,对于不是string的域,通常只须要设置type:

{
    "age": {
        "type": "integer"
    }
}

默认, string 类型域会被认为包含全文。就是说,它们的值在索引前,会经过 一个分析器,针对于这个域的查询在搜索前也会通过一个分析器。

string 域映射的两个最重要 属性是 index 和 analyzer 。

index:

index 属性控制怎样索引字符串。它能够是下面三个值:

一、analyzed:

首先分析字符串,而后索引它。换句话说,以全文索引这个域。

二、not_analyzed:

索引这个域,因此它可以被搜索,但索引的是精确值。不会对它进行分析。

三、no:

不索引这个域。这个域不会被搜索到。

 

string 域 index 属性默认是 analyzed 。若是咱们想映射这个字段为一个精确值(不分析,精确匹配),咱们须要设置它为 not_analyzed:

{
    "tag": {
        "type":     "string",
        "index":    "not_analyzed"
    }
}

注意,只有string域能够被分析,像其余如long、double、date类型,永远不会被分析。

 

analyzer:

对于 analyzed 字符串域,用 analyzer 属性指定在搜索和索引时使用的分析器。默认, Elasticsearch 使用 standard 分析器, 但能够指定一个内置的分析器替代它,例如 whitespace 、 simple 和 english:

{
    "man": {
        "type": "string",
        "analyzer": "english"
    }
}

可是,能够更新一个映射来添加一个新域,但不能将一个存在的域从 analyzed 改成 not_analyzed 。

 

空域:

下面三种域被认为是空的,它们将不会被索引:

"null_value":               null,
"empty_array":              [],
"array_with_null_value":    [ null ]

 

评分查询与过滤查询:

评分查询:

判断这个文档是否匹配,同时它还须要判断这个文档匹配的有多好(相关性得分)。 此查询的典型用法是用于查找如下文档:

一、查找与 full text search 这个词语最佳匹配的文档
二、包含 run 这个词,也能匹配 runs 、 running 、 jog 或者 sprint
三、包含 quick 、 brown 和 fox 这几个词 — 词之间离的越近,文档相关性越高
四、标有 lucene 、 search 或者 java 标签 — 标签越多,相关性越高

评分查询(scoring queries)不只仅要找出 匹配的文档,还要计算每一个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。同时,查询结果并不缓存。

过滤查询:

过滤查询是一个“不评分”或者“过滤”查询。即,这个查询只是简单的问一个问题:“这篇文档是否匹配?”。回答也是很是的简单,yes 或者 no ,两者必居其一。

一、created 时间是否在 2013 与 2014 这个区间?
2、status 字段是否包含 published 这个单词?
三、lat_lon 字段表示的位置是否在指定点的 10km 范围内?

过滤查询(Filtering queries)只是简单的检查包含或者排除,这就使得计算起来很是快。考虑到至少有一个过滤查询(filtering query)的结果是 “稀少的”(不多匹配的文档),而且常用不评分查询(non-scoring queries),结果会被缓存到内存中以便快速读取,因此有各类各样的手段来优化查询结果

相关文章
相关标签/搜索