大数据搜索与挖掘及可视化管理方案 :Elastic Stack 5:Elasticsearch、Logstash、Kibana、X-Pack、Beats (第3版)
上QQ阅读APP看书,第一时间看更新

3.2 基本检索

如果需要构造一个简单的查询语句(含对结果排序,控制返回数据集大小,指定返回字段等),可以使用Elasticsearch基本的检索功能。

3.2.1 检索方式

Elasticsearch的检索,可以通过在浏览器地址栏中输入URL,使用终端curl命令,在可视化工具head的复合查询中输入查询语句等方式进行,可以任选一种方式进行查询。

在Elasticsearch启动的前提下,可以在浏览器中直接使用URL输入(如果同时提供&pretty=ture子句,则输出JSON格式的结果是有缩进的),如:

    http://localhost:9200/{index}/{type}/_search? q={field}:{keyword}&pretty=true

上述方法可以在指定的索引文件名称{index}、指定的类型文件{type}、指定的字段{field}中查找包含{keyword}字符串的结果集,可以为查询指定明确的索引名和类型名(但不是必须的)。如果只给出索引名没有指定类型名,则检索该索引下的所有类型文件;也可以指定多个索引,查询其中的所有或特定的类型文件。

下面列出几种不同的情况:

(1)查询指定索引和指定类型下的信息(指定一个index和一个type名):

    curl-XGET'localhost:9200/it-home/posts/_search? q=category:java&pretty=true'

(2)查询指定索引下所有类型中的信息(指定一个index名,没指定type名):

    curl-XGET'localhost:9200/it-home/_search? q=category:java&pretty=true'

(3)查询所有索引中的信息(没指定index和type名):

    curl-XGET'localhost:9200/_search? q=content:java&pretty=true'

(4)查询多个索引下所有类型中的信息(指定多个index名,没指定type名):

    curl-XGET'localhost:9200/baidu, it-home/_search? q=content:java&pretty=true'

(5)查询多个索引下多个类型中的信息(指定多个index名和多个type名):

    curl-XGET'localhost:9200/baidu, it-home/baike, posts/_search? q=content:java&pretty
    =true'

3.2.2 query查询

利用查询语句进行查询时,在查询体中使用query语句,即可执行对现有存储数据的查询。代码段3.1展示了使用query查询所有数据的查询语句。

    //代码段3.1:使用 query查询所有数据    
    curl-XPOST localhost:9200/baidu/baike/_search-d'{
    "query": {
        "match_all": {}
      }
    }'

3.2.3 from/size查询

在检索过程中可以控制结果的规模以及从哪个结果开始返回,在请求中可以设置相应的属性,其中:

· from:该属性指定从哪个结果开始返回(默认是0)。

· size:该属性指定查询的结果集中包含的最大文档数(默认是10)。

基于上述内容的查询体(不含HTTP方法、索引index名、类型type名等信息,限于篇幅,本章后文多数采取这种表示方法)如代码段3.2所示。

    //代码段3.2:含有 from、size的查询体    
    curl-XPOST localhost:9200/baidu/baike/_search-d'{
    "from":5,
      "size":15,
      "query": {
        "term": {"content": "yoona"}
      }
    }'

3.2.4 查询结果排序

信息检索结果集合的排序策略对用户和网站开发者双方来说都是非常重要的,因为很少有人对排名很靠后的检索结果给与充分的重视,top-10的检索结果对所有用户来说都很重要。有统计表明,约有58%的用户只对检索结果中排名前10位的内容感兴趣,而只有不超过12%的用户才会对排名30位以后的内容感兴趣。

其实,在Elasticsearch的检索结果中,也可以设置不同字段对应的排序权重,在设置好权重以后,在检索结果排序时会用到。例如,在baidu索引的baike类型文件下,通过指定fields数组,在title、content两个字段中搜索给定的关键字。如果需要设置在title字段中出现其权重是2,而在content中出现其权重默认是1,可以参照图3.1中的方法(图左侧是代码实现,图右侧是针对baike数据集的检索结果,后同)。将title字段写成“title^2”,即表示在查询时,设置title字段权重为2;而content字段不加修改,其权重为默认值1。

图3.1 设置不同字段的权重

执行查询过程中如果加入sort子句,就可以不针对某个具体的字段,而是针对默认的排序分数_score进行顺序或逆序的排序。代码段3.3给出对基于match的查询结果的排序方法。

    //代码段3.3:基于_score对结果排序   
    curl-XPOST localhost:9200/baidu/baike/_search-d'{
    "query": {
        "match": {
            "content": "怪味豆"
        }
      },
      "sort": [{"_score": "desc"}]       //排序方式
    }'

对于指定字段的排序而言,可以指定“_last”将无值的结果放在检索结果的最后(如果指定为“_first”,则是将其放在检索结果的首位)。这里需要注意的是,执行这样的语句时,Elasticsearch会开辟一部分内存空间来存解析字段的倒排索引,这一功能称为“fielddata”,默认是禁止的。要实现这样的排序,需要先执行代码段3.4启用fielddata功能,再执行代码段3.5完成检索和排序。

    //代码段3.4: title启用 fielddata   
    curl-XPUT localhost:9200/baidu/_mapping/baike-d'{
                                              //注意使用PUT方法,"索引/_mapping/类型"
      "properties": {
        "title": {                            //指定的field
          "type": "text",
          "fielddata": true                   //启用fielddata
        }
      }
    }'
    //代码段3.5:指定默认值的排序策略    
    curl-XPOST localhost:9200/baidu/baike/_search-d'{
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "title": {               //指定的field
            "order": "desc",
            "missing": "_last"         //对于无值的结果,放在最后显示
          }
        }
      ]
    }'

默认情况下检索结果返回的是完整的JSON格式的文档。用户可以通过_source来引用想要返回的检索结果(即搜索结果hits中的_source字段,如图3.1右侧所示)。也就是说,如果不想返回完整的源文档结构,可以返回指定的部分字段子集,这有点类似于针对关系型数据库管理系统的SQL查询语句中的“select部分字段名from某数据表”中的“部分字段名”的列表部分。下面的代码段3.6是简化了的_source字段,它仍会返回一个叫做_source的字段,但是这里仅包含指定的几个字段。在图3.2的例子中,针对给定的检索词“世界历史人物”进行了分词处理,也就是说,会检索到在指定字段中包含“世界”“世界历史”“历史人物”等特征词的结果集。

    //代码段3.6:通过 match参数指定字段和检索词,排序后返回指定数量的指定字段的检索集    
    curl-XPOST localhost:9200/baidu/baike/_search-d'{
      "query": {
        "match": {
          "字段名称": "世界历史人物"
        },
        "sort": {
            "lastModifyTime": {
            "order": "asc"             //按照这里指定的lastModifyTime字段升序排序
          }
        },
        "_source": ["url", "taglist"], //显示的结果集
        "size":10                      //返回的结果集数量
      }
    }'

3.2.5 高亮搜索词

在查询中使用highlight子句,可以在查询结果中,将每一条结果的一个或多个字段中出现的搜索词高亮显示,高亮的部分将会在查询结果后面以"highlight":{高亮的内容}的格式显示,其中高亮的搜索词默认被双标记<em></em>包围,在实际使用中,可以人为规定这一标记的写法;也可以使用fragment_size指定被高亮的搜索词所在上下文的长度,以及使用number_of_fragments指定包含高亮搜索词的片段数量。代码段3.7实现了对查询结果的正文中的搜索词“学院”的高亮显示,其检索结果如图3.3所示。

图3.2 指定字段子集的检索

    //代码段3.7:高亮显示搜索词   
    curl-XPOST localhost:9200/it-home/posts/_search-d'{
      "query": {
        "match": {
          "content": "学院"                //要高亮显示的搜索词
        }
      },
      "highlight": {
        "pre_tags": ["<spot>"],           //规定高亮标记写法
        "post_tags": ["</spot>"],
        "fields": {
          "content": {
            "fragment_size":150,          //规定高亮搜索词所在上下文长度
            "number_of_fragments":3       //规定显示多少条高亮的结果
          }
        }
      }
    }'

图3.3 搜索词“学院”被<spot>标记并即将高亮显示

3.2.6 查询模板

Elasticsearch允许在查询语句中以固定的template格式设置语句模板和参数。在执行查询时,设置好的参数将被填充到语句中相对应的位置,拼成一条完整的语句执行。代码段3.8实现了基于模板的查询,将字段名、搜索词和搜索结果数量分别作为参数传入查询语句执行查询。

    //代码段3.8:基于模板进行查询    
    curl-XPOST localhost:9200/it-home/posts/_search/template-d'{
                                                 //这里注意末尾要加上template
      "inline": {
        "query": {
          "match": {
            "{{my_field}}": "{{my_value}}"       //设置形式参数,使用{{}}括起来
          }
        },
        "size": "{{my_size}}"
      },
    "params": {
        "my_field": "category",                  //设置实际参数
        "my_value": "java",
        "my_size":5
      }
    }'