教程
关于 入门 为了搜索,你懂的 安装Elasticsearch 与Elasticsearch交互 面向文档 开始第一步 检索文档 分析 教程小结 分布式的特性 下一步 集群内部工作方式 空集群 集群健康 添加索引 增加故障转移 横向扩展 继续扩展 应对故障 数据吞吐 什么是文档? 索引一个文档 检索文档 检查文档是否存在 更新整个文档 创建一个新文档 删除文档 处理冲突 文档局部更新 检索多个文档 更省时的批量操作 结语 分布式文档存储 路由文档到分片 主分片和复制分片如何交互 新建、索引和删除文档 检索文档 局部更新文档 多文档模式 为什么是奇怪的格式? 搜索——基本的工具 空搜索 多索引和多类别 分页 简易搜索 映射和分析 映射及分析 确切值(Exact values) vs. 全文文本(Full text) 倒排索引 分析和分析器 映射 复合核心字段类型 结构化查询 请求体查询 结构化查询 Query DSL 查询与过滤 最重要的查询过滤语句 查询与过滤条件的合并 验证查询 结语 排序 相关性排序 多值字段字符串排序 相关性简介 数据字段 分布式搜索的执行方式 查询阶段 取回阶段 搜索选项 扫描和滚屏 索引管理 创建索引 索引设置 配置分析器 自定义分析器 类型和映射 根对象 元数据:_source 字段 元数据:_all 字段 文档 ID 动态映射 自定义动态索引 默认映射 重新索引数据 索引别名和零停机时间 入门 使文本可以被搜索 动态索引 近实时搜索 持久化变更 合并段 结构化搜索 查找准确值 组合过滤 查询多个准确值 包含,而不是相等 范围 处理 Null 值 关于缓存 过滤顺序 地理坐标点 地理坐标点 通过地理坐标点过滤 地理坐标盒模型过滤器 地理距离过滤器 缓存地理位置过滤器 减少内存占用 按距离排序 Geohashes Geohashes Geohashes 映射 geohash单元过滤器 地理位置聚合 地理位置聚合 按距离聚合 geohash单元聚合器 范围(边界)聚合器 地理形状 地理形状 映射地理形状 索引地理形状 查询地理形状 在查询中使用已索引的形状 地理形状的过滤与缓存 嵌套 嵌套-对象 嵌套-映射 嵌套-查询 嵌套排序 嵌套-集合

发布于 2016-02-29 14:41:44 | 276 次阅读 | 评论: 0 | 来源: 网络整理

类型和映射

类型 在 Elasticsearch 中表示一组相似的文档。类型 由一个 名称(比如 userblogpost)和一个类似数据库表结构的映射组成,描述了文档中可能包含的每个字段的 属性,数据类型(比如 string, integerdate),和是否这些字段需要被 Lucene 索引或储存。

在【文档】一章中,我们说过类型类似关系型数据库中的表格,一开始你可以这样做类比,但是现在值得更深入阐释一下什么是类型,且在 Lucene 中是怎么实现的。

Lucene 如何处理文档

Lucene 中,一个文档由一组简单的键值对组成,一个字段至少需要有一个值,但是任何字段都可以有多个值。类似的,一个单独的字符串可能在分析过程中被转换成多个值。Lucene 不关心这些值是字符串,数字或日期,所有的值都被当成 不透明字节

当我们在 Lucene 中索引一个文档时,每个字段的值都被加到相关字段的倒排索引中。你也可以选择将原始数据 储存 起来以备今后取回。

类型是怎么实现的

Elasticsearch 类型是在这个简单基础上实现的。一个索引可能包含多个类型,每个类型有各自的映射和文档,保存在同一个索引中。

因为 Lucene 没有文档类型的概念,每个文档的类型名被储存在一个叫 _type 的元数据字段上。当我们搜索一种特殊类型的文档时,Elasticsearch 简单的通过 _type 字段来过滤出这些文档。

Lucene 同样没有映射的概念。映射是 Elasticsearch 将复杂 JSON 文档_映射_成 Lucene 需要的扁平化数据的方式。

例如,user 类型中 name 字段的映射声明这个字段是一个 string 类型,在被加入倒排索引之前,它的数据需要通过 whitespace 分析器来分析。

"name": {
    "type":     "string",
    "analyzer": "whitespace"
}

预防类型陷阱

事实上不同类型的文档可以被加到同一个索引里带来了一些预想不到的困难。

想象一下我们的索引中有两种类型:blog_en 表示英语版的博客,blog_es 表示西班牙语版的博客。两种类型都有 title 字段,但是其中一种类型使用 english 分析器,另一种使用 spanish 分析器。

使用下面的查询就会遇到问题:

GET /_search
{
    "query": {
        "match": {
            "title": "The quick brown fox"
        }
    }
}

我们在两种类型中搜索 title 字段,首先需要分析查询语句,但是应该使用哪种分析器呢,spanish 还是 english?Elasticsearch 会采用第一个被找到的 title 字段使用的分析器,这对于这个字段的文档来说是正确的,但对另一个来说却是错误的。

我们可以通过给字段取不同的名字来避免这种错误 —— 比如,用 title_entitle_es。或者在查询中明确包含各自的类型名。

GET /_search
{
    "query": {
        "multi_match": { <1>
            "query":    "The quick brown fox",
            "fields": [ "blog_en.title", "blog_es.title" ]
        }
    }
}

`multi_match` 查询在多个字段上执行 `match` 查询并一起返回结果。 新的查询中 `english` 分析器用于 `blog_en.title` 字段,`spanish` 分析器用于 `blog_es.title` 字段,然后通过综合得分组合两种字段的结果。 这种办法对具有相同数据类型的字段有帮助,但是想象一下如果你将下面两个文档加入同一个索引,会发生什么: * 类型: user ``` { "login": "john_smith" } ``` * 类型: event ``` { "login": "2014-06-01" } ``` Lucene 不在乎一个字段是字符串而另一个字段是日期,它会一视同仁的索引这两个字段。 然而,假如我们试图 _排序_ `event.login` 字段,Elasticsearch 需要将 `login` 字段的值加载到内存中。像我们在 【字段数据介绍】中提到的,它将 _任意文档_ 的值加入索引而不管它们的类型。 它会尝试加载这些值为字符串或日期,取决于它遇到的第一个 `login` 字段。这可能会导致预想不到的结果或者以失败告终。 提示:为了保证你不会遇到这些冲突,建议在同一个索引的每一个类型中,确保用_同样的方式_映射_同名_的字段

最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务