Elasticsearch搜索

目录

第1关:Elasticsearch搜索

代码

第2关:Elasticsearch映射和分析

代码

第3关:Elasticsearch映射

代码


第1关:Elasticsearch搜索

任务描述

本关任务:根据所学知识,完成 Elasticsearch 文档的相关搜索。

相关知识
为了完成本关任务,你需要掌握:

什么是空搜索;
多索引、多类型如何搜索;
如何做到分页搜索;
什么是轻量搜索。
Elasticsearch 不只会存储(stores)文档,为了能被搜索到也会为文档添加索引(indexes),这也是为什么我们使用结构化的 JSON 文档,而不是无结构的二进制数据。

文档中的每个字段都将被索引并且可以被查询。不仅如此,在简单查询时,Elasticsearch 可以使用所有(all) 这些索引字段,以惊人的速度返回结果。这是你永远不会考虑用传统数据库去做的一些事情。

搜索(search) 可以做到:

在类似于 gender 或者 age 这样的字段上使用结构化查询,join_date 这样的字段上使用排序,就像 SQL 的结构化查询一样;

全文检索,找出所有匹配关键字的文档并按照相关性(relevance)排序后返回结果。

代码
#!/bin/bash
# 请在此处编写命令
# ********** Begin ********** #
curl -H "Content-Type: application/json" -XGET 'http://localhost:9200/store/books/_search?q=+title:(Kingdoms+Margin)&pretty'
# ********** End ********** #

第2关:Elasticsearch映射和分析

任务描述
本关任务:根据所学知识,使用 IK 分词器对文本内容进行分词。

相关知识
为了完成本关任务,你需要掌握:

Elasticsearch 精确值和全文;
倒排索引;
分析与分析器。
Elasticsearch 精确值和全文
当摆弄索引里面的数据时,我们发现一些奇怪的事情。一些事情看起来被打乱了:在我们的索引中有四条索引是包含 2014 的,只有一条包含日期 2014-09-15 ,但是看一看下面查询命中的总数 (total):

/_search?q=2014  # 4 条
/_search?q=2014-09-15 # 1 条
/_search?q=publish_date:2014-09-15 # 1 条
/_search?q=publish_date:2014 # 0 条
为什么在 _all 字段查询日期返回所有推文,而在 date 字段只查询年份却没有返回结果?为什么我们在 _all 字段和 publish_date 字段的查询结果有差别?

推测起来,这是因为数据在 _all 字段与 publish_date 字段的索引方式不同。所以,通过请求 store 索引中 books 类型的映射(或模式定义),让我们看一看 Elasticsearch 是如何解释我们文档结构的:

curl -H "Content-Type: application/json" -XGET 'http://localhost:9200/store/_mapping/books?pretty'
执行结果:

{
  "store" : {
    "mappings" : {
      "books" : {
        "properties" : {
          "name" : {
            "properties" : {
              "first" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              },
              "last" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              }
            }
          },
          "price" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
          "publish_date" : {
            "type" : "date"
          },
          "title" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    }
  }
}
基于对字段类型的猜测, Elasticsearch 动态为我们产生了一个映射。这个响应告诉我们 publish_date 字段被认为是 date 类型的。由于 _all 是默认字段,所以没有提及它。但是我们知道 _all 字段是 string 类型的。

所以 publish_date 字段和 string 字段索引方式不同,因此搜索结果也不一样。这完全不令人吃惊。你可能会认为核心数据类型 strings、numbers、Booleans 和 dates 的索引方式有稍许不同。没错,他们确实稍有不同。

但是,到目前为止,最大的差异在于代表精确值(它包括 string 字段)的字段和代表 全文的字段。这个区别非常重要——它将搜索引擎和所有其他数据库区别开来。

Elasticsearch 中的数据可以概括的分为两类:精确值和全文。

精确值:如它们听起来那样精确。例如日期或者用户 ID,但字符串也可以表示精确值,例如用户名或邮箱地址。对于精确值来讲,Foo 和 foo 是不同的,2014 和 2014-09-15 也是不同的。

另一方面,全文是指文本数据(通常以人类容易识别的语言书写),例如一个推文的内容或一封邮件的内容。

例如,考虑这条语句:

May is fun but June bores me.
May 指的是月份还是人?

精确值很容易查询。结果是二进制的:要么匹配查询,要么不匹配。这种查询很容易用 SQL 表示:

WHERE name    = "John Smith"
  AND user_id = 2
  AND date    > "2014-09-15"
查询全文数据要微妙的多。我们问的不只是“这个文档匹配查询吗”,而是“该文档匹配查询的程度有多大?”换句话说,该文档与给定查询的相关性如何?

我们很少对全文类型的域做精确匹配。相反,我们希望在文本类型的域中搜索。不仅如此,我们还希望搜索能够理解我们的意图 :

搜索 UK ,会返回包含 United Kindom 的文档;
搜索 jump ,会匹配 jumped,jumps,jumping,甚至是 leap;
搜索 johnny walker 会匹配 Johnnie Walker, johnnie depp 应该匹配 Johnny Depp;
搜索 fox news hunting 应该返回福克斯新闻( Foxs News )中关于狩猎的故事,同时, fox hunting news 应该返回关于猎狐的故事;
为了促进这类在全文域中的查询,Elasticsearch 首先分析文档,之后根据结果创建 倒排索引。接下来,我们会讨论倒排索引和分析过程。

倒排索引
Elasticsearch 使用一种称为倒排索引的结构,它适用于快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表。

例如,假设我们有两个文档,每个文档的 content 域包含如下内容:

The quick brown fox jumped over the lazy dog
Quick brown foxes leap over lazy dogs in summer
为了创建倒排索引,我们首先将每个文档的 content 域拆分成单独的 词(我们称它为 词条 或 tokens),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。结果如下所示:

Term      Doc_1  Doc_2
-------------------------
Quick   |       |  √
The     |   √   |
brown   |   √   |  √
dog     |   √   |
dogs    |       |  √
fox     |   √   |
foxes   |       |  √
in      |       |  √
jumped  |   √   |
lazy    |   √   |  √
leap    |       |  √
over    |   √   |  √
quick   |   √   |
summer  |       |  √
the     |   √   |
------------------------
现在,如果我们想搜索 quick brown ,我们只需要查找包含每个词条的文档:

Term

### 如何使用 Elasticsearch 进行搜索操作 #### 安装与启动 Elasticsearch Elasticsearch 默认会在 `http://localhost:9200/` 上运行,可以通过浏览器访问该地址或者使用命令行工具如 `curl` 来验证其状态。如果返回 JSON 格式的集群健康状况,则说明安装成功并正在运行[^1]。 ```bash curl -X GET "localhost:9200/_cluster/health?pretty" ``` #### 创建索引 为了能够执行搜索,在此之前需要创建一个索引来保存文档数据。这里展示了一个简单的例子: ```json PUT /my-index-000001 { "settings": { "analysis": { "analyzer": { "ik_analyzer": { "type": "custom", "tokenizer": "ik_max_word" } } } }, "mappings": { "properties": { "title": { "type": "text", "analyzer": "ik_analyzer" } } } } ``` 上述配置中包含了自定义分析器 `ik_analyzer` 的设置,它基于 IK 分词插件实现更精准的文字处理功能[^2]。 #### 插入文档 接下来向刚刚建立好的索引里添加一些测试记录以便稍后检索: ```json POST /my-index-000001/_doc/ { "title": "这是一个用于演示ES搜索能力的例子" } ``` #### 执行基本全文本搜索 现在可以尝试发起一次简单匹配查询请求来获取含有特定关键词的结果集: ```json GET /my-index-000001/_search { "query": { "match": { "title": "演示 ES 搜索" } } } ``` 对于更高维度的数据比如图像特征描述符或是自然语言表示模型产生的数值型数组(即所谓的“向量”),可以从版本7.2.0起通过内置的支持来进行高效相似度计算[^3]。这允许开发者构建复杂的推荐系统或语义理解应用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小柒_02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值