精华内容
下载资源
问答
  • Mapping

    千次阅读 2019-08-27 11:14:05
    mapping是定义文档及其字段是如何存储和索引的程序。例如,使用mapping定义: 哪个字符串字段应该视为全文字段 哪个字段包含数字,日期,或地理位置 日期的格式 自定义规则来控制动态添加字段 mapping type 每个...

    mapping是定义文档及其字段是如何存储和索引的程序。例如,使用mapping定义:

    • 哪个字符串字段应该视为全文字段
    • 哪个字段包含数字,日期,或地理位置
    • 日期的格式
    • 自定义规则来控制动态添加字段

    mapping type

    每个索引都有mapping type来决定文档如何被索引。mapping type包含:

    • meta-fields: 比如_index, _type, _id, _source字段,用来定制文档相关的元数据
    • fields or properties:相关文档的字段列表或者properties

    字段数据类型

    每个字段都有数据类型,可以是如下:

    • 简单的类型:text, keyword, date, long, double, boolean, ip
    • 支持JSON这种层次结构的:object, nested
    • 专门的类型:geo_point, geo_shape, completion

    根据不同的目的以不同的方式来索引相同的字段通常很有用。比如,同样的字段可以索引为text类型以便进行全文搜索,也可以作为keyword类型用来排序或聚合。或者同样的值使用不同的分词器。

    大部分字段都支持fields参数的多字段搜索。

    核心数据类型

    • 字符串

      PUT my_index
      {
        "mappings": {
          "properties": {
            "full_name": {
              "type":  "text"
            }
          }
        }
      }
      
      • text 用于全文索引,会被分词处理。适用于文章内容,产品介绍之类的信息。可以接收以下参数:

        • analyzer 指定分词器,同时适用于索引时和搜索时(除非被search_analyzer覆盖),默认值是索引默认的分词器,或者standard分词器
        • boost 字段级别的查询时提升(权重),接收浮点数,默认是1.0
        • eager_global_ordinals 刷新时是否重新加载全局顺序?默认是false。建议对经常用于词条聚合的此段启动该特性。
        • fielddata 该字段是否能使用内存字段数据用来排序,聚合,或者脚本计算?默认false
        • fielddata_frequency_filter 专家设置:当fielddata启用时,是否允许决定哪些值被载入内存,默认情况下加载所有值
        • fields 多字段(multi-fields)允许出于不同的目的以多种方式来索引相同的字段,比如一个字段用于搜索,一个多字段用于排序和聚合,或者对同样的字符串使用不同的分词器
        • index 字段是否可被搜索,默认true
        • index_options 索引中应该存储什么信息用于搜索和高亮,默认是positions
        • index_prefixes 如果启用,2~5个字符的词条前缀将会被索引为一个单独的字段,有助于提高前缀搜索的效率。
        • index_phrases 如果允许,词组会被索引为单独的字段。这使得精确的短语查询更高效。注意,只有当停用词没有被移除时,这个才最有效,因为包含停用词的短语不会使用子字段,而是使用标准的短语查询。默认值是false
        • norms 打分时是否考虑字段长度,默认true
        • position_increment_gap 略
        • store 字段值是否在_source字段外,被独立存储和检索,默认false
        • search_analyzer 指定搜索时的分词器,默认是analyzer 参数的设置
        • search_quote_analyzer 没啥用
        • similarity 使用哪种打分算法,默认是BM25
        • term_vector 略
      • keyword 关键词,适用于标签,状态码,邮件地址,域名,商标等。用于过滤,排序,和聚合,关键词只支持精确搜索。

        PUT my_index
        {
          "mappings": {
            "properties": {
              "tags": {
                "type":  "keyword"
              }
            }
          }
        }
        

        支持的参数如下:

        • ignore_above 默认是2147483647,超过这一长度的字符串无法索引。但是默认的动态mapping会覆盖这个值为ignore_above:256
        • 其他和text类似,具体参见官网
    • 数字

      • long -2^63 ~ 2^63-1

      • integer -2^31 ~ 2^31-1

      • short -32768 ~ 32768

      • byte -128 ~ 127

      • double 64位双精度浮点数

      • float 32位双精度浮点数

      • half_float 16位双精度浮点数

      • scaled_float 略

        PUT my_index
        {
          "mappings": {
            "properties": {
              "number_of_bytes": {
                "type": "integer"
              },
              "time_in_seconds": {
                "type": "float"
              },
              "price": {
                "type": "scaled_float",
                "scaling_factor": 100
              }
            }
          }
        }
        
      • 数字类型的字段支持以下参数:

        • coerce 强制转换字符串为数字,截断分数为整数,默认是true
        • 其他参数参考官网
    • date,JSON没有日期类型,因此ES中的日期可以是

      • 包含日期格式的字符串,比如:"2015-01-01" or "2015/01/01 12:10:30"
      • 时间的毫秒数
      • 时间的整数

      在ES内部,日期会被转换为UTC时间(如果指定了时区),并且存储为代表时间毫秒数的长整数。对于日期的查询会被转化为对这个长整数的范围查询,结果再转化为以该字段定义的日期格式的字符串。日期格式可以自定义,如果没有指定format,会使用如下默认值:

      "strict_date_optional_time||epoch_millis"
      

      这意味它可以接受strict_date_optional_time支持的格式,或者毫秒数,例如:

      PUT my_index
      {
        "mappings": {
          "properties": {
            "date": {
              "type": "date" // 不指定format,那就使用上面提到的默认值
            }
          }
        }
      }
      
      PUT my_index/_doc/1
      { "date": "2015-01-01" }   // 纯日期
      
      PUT my_index/_doc/2
      { "date": "2015-01-01T12:10:30Z" } //日期+时间
      
      PUT my_index/_doc/3
      { "date": 1420070400001 }  // 毫秒数
      
      GET my_index/_search
      {
        "sort": { "date": "asc"} 
      }
      

      自定义多种日期格式:

      PUT my_index
      {
        "mappings": {
          "properties": {
            "date": {
              "type":   "date",
              "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            }
          }
        }
      }
      
    • 布尔

      • boolean: true, false
    • 二进制

      • binary

        PUT my_index
        {
          "mappings": {
            "properties": {
              "name": {
                "type": "text"
              },
              "blob": {
                "type": "binary"
              }
            }
          }
        }
        
        PUT my_index/_doc/1
        {
          "name": "Some binary blob",
          "blob": "U29tZSBiaW5hcnkgYmxvYg=="   // base64编码后的二进制
        }
        
    • 范围

      • integer_range: -2^31 ~ 2^31-1
      • float_range
      • long_range
      • double_range
      • date_range

      示例:范围字段在索引文档时,需要使用gte, lte

      PUT range_index
      {
        "settings": {
          "number_of_shards": 2
        },
        "mappings": {
          "properties": {
            "expected_attendees": {
              "type": "integer_range"
            },
            "time_frame": {
              "type": "date_range", 
              "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            }
          }
        }
      }
      
      PUT range_index/_doc/1?refresh
      {
        "expected_attendees" : {   // 索引文档时需要指定范围
          "gte" : 10,
          "lte" : 20
        },
        "time_frame" : { 
          "gte" : "2015-10-31 12:00:00", 
          "lte" : "2015-11-01"
        }
      }
      

    复杂数据类型

    • object 对象

      JSON文档本身就是一种结构话的数据,比如:

      PUT my_index/_doc/1
      { 
        "region": "US",
        "manager": { // manager对象
          "age":     30,
          "name": { 
            "first": "John",
            "last":  "Smith"
          }
        }
      }
      

      ES内部会将以上文档索引为扁平的键值对,类似于:

      {
        "region":             "US",
        "manager.age":        30,
        "manager.name.first": "John",
        "manager.name.last":  "Smith"
      }
      

      以上文档的mapping如下:

      PUT my_index
      {
        "mappings": {
          "properties": { 
            "region": {
              "type": "keyword"
            },
            "manager": { // manager作为内部对象,可以有自己的age, name
              "properties": {
                "age":  { "type": "integer" },
                "name": { 
                  "properties": {
                    "first": { "type": "text" },
                    "last":  { "type": "text" }
                  }
                }
              }
            }
          }
        }
      }
      

      object字段支持参数如下:

      • dynamic 是否支持对象的properties动态增加字段,默认"true"
      • enabled 是否允许对象字段直接解析索引JSON,默认"true"
    • nested 嵌套对象,用来支持多个对象构成的数组,mapping如下:

      PUT my_index
      {
        "mappings": {
          "properties": {
            "user": {
              "type": "nested" 
            }
          }
        }
      }
      

      索引文档:

      PUT my_index/_doc/1
      {
        "group" : "fans",
        "user" : [
          {
            "first" : "John",
            "last" :  "Smith"
          },
          {
            "first" : "Alice",
            "last" :  "White"
          }
        ]
      }
      

      查询示例1:

      GET my_index/_search
      {
        "query": {
          "nested": {
            "path": "user",
            "query": {
              "bool": {
                "must": [
                  { "match": { "user.first": "Alice" }},
                  { "match": { "user.last":  "Smith" }} 
                ]
              }
            }
          }
        }
      }
      

      以上查询无法匹配任何结果,因为"Alice"和"Smith"不在同一个嵌套对象中。

      查询示例2:

      GET my_index/_search
      {
        "query": {
          "nested": {
            "path": "user",
            "query": {
              "bool": {
                "must": [
                  { "match": { "user.first": "Alice" }},
                  { "match": { "user.last":  "White" }} 
                ]
              }
            },
            "inner_hits": { // 匹配的嵌套文档进行高亮
              "highlight": {
                "fields": {
                  "user.first": {}
                }
              }
            }
          }
        }
      }
      

      由于"Alice"和"White"在同一个嵌套对象中,因此可以查询可以匹配。

    地理信息数据类型

    • geo_point
    • geo_shape

    专门数据类型

    • ip

    • completion 自动完成(搜索建议)

    • token_count:字符串中的词条的数量

    • murmur3 索引时计算内容的哈希值并存储在索引中

    • annotated-text 索引包含特殊标记的文本(用于标识命名实体)

    • join 定义索引中文档的父子关系

      PUT my_index
      {
        "mappings": {
          "properties": {
            "my_join_field": { 
              "type": "join",
              "relations": {
                "question": "answer"  // question和answer是父子关系
              }
            }
          }
        }
      }
      
    • alias 已存在字段定义别名

    • rank 记录数字特征来提高查询的命中

    • vector 向量

    数组

    ES中,数组不需要专门的字段。默认情况下,任何字段都可以包括零个或多个值,但是所有的值必须具有相同的数据类型。

    动态mapping

    字段和mapping类型不需要事先定义,因此在索引文档时,新字段的名字将会自动添加(可以添加到根字段,或者是object和nested子字段)

    详尽mapping

    比起Elasticsearch的“猜测”,你更清楚你的数据。所以一开始可以用动态mapping,到某个阶段后,你可以自己定制mapping。

    你可以在创建索引(集)时创建字段mapping,然后通过PUT mapping API来向已经存在的索引(集)增加字段。

    更新现存字段的mapping

    除了文档之外,现存字段的mapping无法更新。更新字段意味着已经索引的文档会失效。相反,你应该用正确的mapping创建一个新的索引,然后reindex数据到新的索引中。如果你只是想重命名某个字段而不改变mapping,可以使用alias字段。

    示例

    创建索引时指定mapping:

    PUT my_index 
    {
      "mappings": {
        "properties": {
          "title":    { "type": "text"  }, 
          "name":     { "type": "text"  }, 
          "age":      { "type": "integer" },  
          "created":  {
            "type":   "date", 
            "format": "strict_date_optional_time||epoch_millis"
          }
        }
      }
    }
    

    废除mapping types

    7.0之后废除,原先需要指定type的地方,都用_doc代替。

    由于第一版ES中,所有的文档存储在单个索引中,比如user类型的文档和blog类型的文档,他们的数据结构不同,为了区分,就分别定义了user类型,和blog类型。每个文档都有一个_type元字段来标明类型,搜索时也需要指定类型名。另外,在单个索引中,不同的类型的文档可以拥有相同的_id值,因此要唯一标识一个资源,需要通过_type_id

    更多信息查看具体查看官网

    mapping参数

    • normalizer 相当于keyword字段的analyzer,只不过保证语义分析链最终返回一个词条

    • analyzer 略

    • boost 字段权重,默认1.0

    • copy_to 将多个字段的值放到一个字段

      PUT my_index
      {
        "mappings": {
          "properties": {
            "first_name": {
              "type": "text",
              "copy_to": "full_name" 
            },
            "last_name": {
              "type": "text",
              "copy_to": "full_name" 
            },
            "full_name": {
              "type": "text"
            }
          }
        }
      }
      
    • fields 对同一字段指定不同的数据类型和分词器

      PUT my_index
      {
        "mappings": {
          "properties": {
            "city": {
              "type": "text",
              "fields": {
                "raw": { 
                  "type":  "keyword"
                }
              }
            }
          }
        }
      }
      

      city用于全文检索,city.raw作为keyword,可以支持排序聚合

    • completion

    • 其他略,参考text数据类型的参数

    展开全文
  • User Story Mapping

    2019-02-13 10:52:56
    用户故事方式来介绍产品规划,英文版,一边学英文,一边学产品
  • CookieMapping

    2014-05-19 15:37:40
    RTB竞价中CookieMapping解决DSP Cookie于Adexchange Cookie的对接匹配问题。 1. google adexchange等在网站上种Cookie,记录用户信息,生成google_customer_nid 2. 用户在浏览网站时,有广告请求,Adx将请求302...

    RTB竞价中CookieMapping解决DSP Cookie于Adexchange Cookie的对接匹配问题。

    1. google adexchange等在网站上种Cookie,记录用户信息,生成google_customer_nid

    2. 用户在浏览网站时,有广告请求,Adx将请求302重定向到DSP,并且携带加密后的google_user_id。这样DSP就能在用户电脑种cookie,并且建立映射关系,

        google_user_id ------> dsp_cookie_id


    背景:

    RTB允许DSP在Adexchange上做交易,在接入Adexchange的流量PV时,针对每次PV,每个用户分析进行竞价,从而购买到ROI较高的流量,所以RTB交易在于人,对于人群的分析数据。


    cookie mapping的实现

    1. 用户请求

    <img src="http://cm.g.doubleclick.net/pixel?google_nid=1234&google_cm" />
    2. google返回重定向 和 google_user_id

    http://ad.network.com/pixel?google_gid=dGhpcyBpcyBhbiBleGFtGxl&google_cver=1

    3. 用户浏览器请求DSP PV

    4. DSP接受到Cookie进行映射


    当没有cookie时

    1. ExampleNews.com 将会显示并调用 Google (DFP) 的广告。
    2. 广告单元符合动态分配资格,因此 Ad Exchange 会调用 FinestDSP(以及其他 DSP)。
    3. FinestDSP 在其出价引擎中处理此调用。
    4. FinestDSP 赢得竞价,并将广告和匹配标记(像素)传送至 Ad Exchange。
    5. Ad Exchange 向小丽投放 FinestDSP 的广告和匹配标记,并设置她的 DoubleClick Cookie。
    6. 匹配标记调用 Google 的 Cookie 匹配服务。
    7. Cookie 匹配服务读取小丽的 DoubleClick Cookie,并将设好 google_user_id 的重定向传送至 FinestDSP。
    8. 浏览器加载 FinestDSP 的网址。
    9. FinestDSP 生成 Cookie,并将此 Cookie 存储在其匹配表中与小丽的 google_user_id 相对应的位置。
    10. FinestDSP 将其 Cookie 放到小丽的浏览器中,并在响应中提供一个空白的 1x1 像素。
    这个空白的像素是种cookie时的副产品。不发挥作用。


    存在cookie时

    1. 小丽会看到网页,同时,html 代码会包含向 Google 请求广告的调用。
    2. 在广告竞价期间,DoubleClick Ad Exchange 会向实时出价合作伙伴 FinestDSP 发出调用请求,让其选择是否要对展示进行出价。
    3. 买方收到包含展示信息和 google_user_id 的广告调用。
    4. FinestDSP 在其匹配表中查找 google_user_id,以找出一周前创建的 Cookie(第 1 种情况)。
    5. FinestDSP 利用与其 Cookie 相关的信息,对展示进行出价并赢得这次展示机会。
    6. FinestDSP 根据所掌握的信息向小丽投放与其兴趣相符的广告。
    在第五步,FinestDSP 竞价的决定因素是掌握的信息。这些信息除了ad exchange网址带过来的一些关于ssp的参数,还有FinestDSP以前展示的广告被小丽点击的情况,还有的信息包括FinestDSP从ssp那里收集到的关于小丽的信息。

    但是它的信息会非常不完整,尤其是像广告被点击的情况,这个很稀疏。所以说关于用户小丽的信息很少。


    这就是dmp可以发挥作用的地方。




    展开全文
  • User Experience Mapping

    2017-07-30 15:06:21
    Get closer to your users and create better products for them。了解你的用户并为他们打造更好的产品
  • ES 修改mapping

    千次阅读 2020-02-19 16:21:36
    场景 在mysql中 我们经常遇到产品修改需求 我们可能会在原有数据库表基础上 对字段 索引 ...ES的mapping一旦设置了之后 是不能修改的 因为ES默认是对所有字段进行索引 如果你修改了mapping 那么已经索引过的数据...

    场景

    在mysql中  我们经常遇到产品修改需求   我们可能会在原有数据库表基础上   对字段  索引  类型进行修改

    比如  增加一个字段   添加一个字段的索引  又或者修改某个字段的类型

    一切都看起来这么自然  不过在ES这里却是行不通的

    ES的mapping一旦设置了之后  是不能修改的   因为ES默认是对所有字段进行索引   如果你修改了mapping  那么已经索引过的数据就必须全部重新索引一遍  ES没有提供这个机制

    解决

    不过我们有另外一种解决方案类似与运维中的滚动发布

    利用别名

    说穿了其实很简单

    比如我们创建了一个索引张三  我们给他起一个别名A  我们在搜索的时候就可以在别名中搜索  别名会自动映射到张三

    这时候如果张三满足不了我们的需求,我们要修改张三。我们可以创建一个李四的索引(修改后的张三索引mapping)

    然后同步数据并索引到李四

    这时候我们把别名映射 从A->张三  变成  A->李四   就可以实现无缝切换了

    实际操作

    创建张三索引

    修改索引别名

    创建李四索引(在张三的基础上增加了一个age字段)

    修改别名映射

    大功告成    这样搜索A索引  就是在搜索新的李四了

    通过这几个步骤就实现了平滑切换 零停机

    这里面切换别名的操作是原子性的  所以不用担心数据搜索错乱的问题

    {
        "actions" : [
            { "remove" : { "index" : "zhangsan", "alias" : "a" } },
            { "add" : { "index" : "lisi", "alias" : "a" } }
        ]
    }

     

    展开全文
  • Mapping映射

    千次阅读 2018-12-06 14:40:34
    text取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于...


    前言

    声明:本博客根据ELasticsearch官网文档翻译整理,转载请注明出处:http://blog.csdn.net/napoay


    一、Field datatype(字段数据类型)

    1.1string类型

    ELasticsearch 5.X之后的字段类型不再支持string,由text或keyword取代。 如果仍使用string,会给出警告。

    测试:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "title": {
              "type":  "string"
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结果:

    #! Deprecation: The [string] field is deprecated, please use [text] or [keyword] instead on [title]
    {
      "acknowledged": true,
      "shards_acknowledged": true
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2 text类型

    text取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合(termsAggregation除外)。

    把full_name字段设为text类型的Mapping如下:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "full_name": {
              "type":  "text"
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.3 keyword类型

    keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到。

    1.4 数字类型

    对于数字类型,ELasticsearch支持以下几种:

    类型取值范围
    long-2^63至2^63-1
    integer-2^31至2^31-1
    short-32,768至32768
    byte-128至127
    double64位双精度IEEE 754浮点类型
    float32位单精度IEEE 754浮点类型
    half_float16位半精度IEEE 754浮点类型
    scaled_float缩放类型的的浮点数(比如价格只需要精确到分,price为57.34的字段缩放因子为100,存起来就是5734)

    对于float、half_float和scaled_float,-0.0和+0.0是不同的值,使用term查询查找-0.0不会匹配+0.0,同样range查询中上边界是-0.0不会匹配+0.0,下边界是+0.0不会匹配-0.0。

    对于数字类型的数据,选择以上数据类型的注意事项:

    1. 在满足需求的情况下,尽可能选择范围小的数据类型。比如,某个字段的取值最大值不会超过100,那么选择byte类型即可。迄今为止吉尼斯记录的人类的年龄的最大值为134岁,对于年龄字段,short足矣。字段的长度越短,索引和搜索的效率越高。
    2. 优先考虑使用带缩放因子的浮点类型。

    例子:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "number_of_bytes": {
              "type": "integer"
            },
            "time_in_seconds": {
              "type": "float"
            },
            "price": {
              "type": "scaled_float",
              "scaling_factor": 100
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.5 Object类型

    JSON天生具有层级关系,文档会包含嵌套的对象:

    PUT my_index/my_type/1
    { 
      "region": "US",
      "manager": { 
        "age":     30,
        "name": { 
          "first": "John",
          "last":  "Smith"
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上面的文档中,整体是一个JSON,JSON中包含一个manager,manager又包含一个name。最终,文档会被索引成一平的key-value对:

    {
      "region":             "US",
      "manager.age":        30,
      "manager.name.first": "John",
      "manager.name.last":  "Smith"
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    上面文档结构的Mapping如下:

    PUT my_index
    {
      "mappings": {
        "my_type": { 
          "properties": {
            "region": {
              "type": "keyword"
            },
            "manager": { 
              "properties": {
                "age":  { "type": "integer" },
                "name": { 
                  "properties": {
                    "first": { "type": "text" },
                    "last":  { "type": "text" }
                  }
                }
              }
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    1.6 date类型

    JSON中没有日期类型,所以在ELasticsearch中,日期类型可以是以下几种:

    1. 日期格式的字符串:e.g. “2015-01-01” or “2015/01/01 12:10:30”.
    2. long类型的毫秒数( milliseconds-since-the-epoch)
    3. integer的秒数(seconds-since-the-epoch)

    日期格式可以自定义,如果没有自定义,默认格式如下:

    "strict_date_optional_time||epoch_millis"
     
    • 1
    • 1

    例子:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "date": {
              "type": "date" 
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    { "date": "2015-01-01" } 
    
    PUT my_index/my_type/2
    { "date": "2015-01-01T12:10:30Z" } 
    
    PUT my_index/my_type/3
    { "date": 1420070400001 } 
    
    GET my_index/_search
    {
      "sort": { "date": "asc"} 
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    查看三个日期类型:

    {
      "took": 0,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "2",
            "_score": 1,
            "_source": { "date": "2015-01-01T12:10:30Z" } },
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "1",
            "_score": 1,
            "_source": { "date": "2015-01-01" } },
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "3",
            "_score": 1,
            "_source": { "date": 1420070400001 } }
        ]
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    排序结果:

    {
      "took": 2,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 3,
        "max_score": null,
        "hits": [
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "1",
            "_score": null,
            "_source": { "date": "2015-01-01" },
            "sort": [ 1420070400000 ] },
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "3",
            "_score": null,
            "_source": { "date": 1420070400001 },
            "sort": [ 1420070400001 ] },
          {
            "_index": "my_index",
            "_type": "my_type",
            "_id": "2",
            "_score": null,
            "_source": { "date": "2015-01-01T12:10:30Z" },
            "sort": [ 1420114230000 ] }
        ]
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    1.7 Array类型

    ELasticsearch没有专用的数组类型,默认情况下任何字段都可以包含一个或者多个值,但是一个数组中的值要是同一种类型。例如:

    1. 字符数组: [ “one”, “two” ]
    2. 整型数组:[1,3]
    3. 嵌套数组:[1,[2,3]],等价于[1,2,3]
    4. 对象数组:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }]

    注意事项:

    • 动态添加数据时,数组的第一个值的类型决定整个数组的类型
    • 混合数组类型是不支持的,比如:[1,”abc”]
    • 数组可以包含null值,空数组[ ]会被当做missing field对待。

    1.8 binary类型

    binary类型接受base64编码的字符串,默认不存储也不可搜索。

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "name": {
              "type": "text"
            },
            "blob": {
              "type": "binary"
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "name": "Some binary blob",
      "blob": "U29tZSBiaW5hcnkgYmxvYg==" 
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    搜索blog字段:

    GET my_index/_search
    {
      "query": {
        "match": {
          "blob": "test" 
        }
      }
    }
    
    返回结果:
    {
      "error": {
        "root_cause": [
          {
            "type": "query_shard_exception",
            "reason": "Binary fields do not support searching",
            "index_uuid": "fgA7UM5XSS-56JO4F4fYug",
            "index": "my_index"
          }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [
          {
            "shard": 0,
            "index": "my_index",
            "node": "3dQd1RRVTMiKdTckM68nPQ",
            "reason": {
              "type": "query_shard_exception",
              "reason": "Binary fields do not support searching",
              "index_uuid": "fgA7UM5XSS-56JO4F4fYug",
              "index": "my_index"
            }
          }
        ]
      },
      "status": 400
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    Base64加密、解码工具:http://www1.tc711.com/tool/BASE64.htm

    1.9 ip类型

    ip类型的字段用于存储IPV4或者IPV6的地址。

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "ip_addr": {
              "type": "ip"
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "ip_addr": "192.168.1.1"
    }
    
    GET my_index/_search
    {
      "query": {
        "term": {
          "ip_addr": "192.168.0.0/16"
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    1.10 range类型

    range类型支持以下几种:

    类型范围
    integer_range-2^31至2^31-1
    float_range32-bit IEEE 754
    long_range-2^63至2^63-1
    double_range64-bit IEEE 754
    date_range64位整数,毫秒计时

    range类型的使用场景:比如前端的时间选择表单、年龄范围选择表单等。
    例子:

    PUT range_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "expected_attendees": {
              "type": "integer_range"
            },
            "time_frame": {
              "type": "date_range", 
              "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            }
          }
        }
      }
    }
    
    PUT range_index/my_type/1
    {
      "expected_attendees" : { 
        "gte" : 10,
        "lte" : 20
      },
      "time_frame" : { 
        "gte" : "2015-10-31 12:00:00", 
        "lte" : "2015-11-01"
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    上面代码创建了一个range_index索引,expected_attendees的人数为10到20,时间是2015-10-31 12:00:00至2015-11-01。

    查询:

    POST range_index/_search
    {
      "query" : {
        "range" : {
          "time_frame" : { 
            "gte" : "2015-08-01",
            "lte" : "2015-12-01",
            "relation" : "within" 
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    查询结果:

    {
      "took": 2,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 1,
        "max_score": 1,
        "hits": [
          {
            "_index": "range_index",
            "_type": "my_type",
            "_id": "1",
            "_score": 1,
            "_source": { "expected_attendees": { "gte": 10, "lte": 20 }, "time_frame": { "gte": "2015-10-31 12:00:00", "lte": "2015-11-01" } } }
        ]
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1.11 nested类型

    nested嵌套类型是object中的一个特例,可以让array类型的Object独立索引和查询。 使用Object类型有时会出现问题,比如文档 my_index/my_type/1的结构如下:

    PUT my_index/my_type/1
    {
      "group" : "fans",
      "user" : [ 
        {
          "first" : "John",
          "last" :  "Smith"
        },
        {
          "first" : "Alice",
          "last" :  "White"
        }
      ]
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    user字段会被动态添加为Object类型。
    最后会被转换为以下平整的形式:

    {
      "group" :        "fans",
      "user.first" : [ "alice", "john" ],
      "user.last" :  [ "smith", "white" ]
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    user.first和user.last会被平铺为多值字段,Alice和White之间的关联关系会消失。上面的文档会不正确的匹配以下查询(虽然能搜索到,实际上不存在Alice Smith):

    GET my_index/_search
    {
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }}
          ]
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    使用nested字段类型解决Object类型的不足:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "user": {
              "type": "nested" 
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "group" : "fans",
      "user" : [
        {
          "first" : "John",
          "last" :  "Smith"
        },
        {
          "first" : "Alice",
          "last" :  "White"
        }
      ]
    }
    
    GET my_index/_search
    {
      "query": {
        "nested": {
          "path": "user",
          "query": {
            "bool": {
              "must": [
                { "match": { "user.first": "Alice" }},
                { "match": { "user.last":  "Smith" }} 
              ]
            }
          }
        }
      }
    }
    
    GET my_index/_search
    {
      "query": {
        "nested": {
          "path": "user",
          "query": {
            "bool": {
              "must": [
                { "match": { "user.first": "Alice" }},
                { "match": { "user.last":  "White" }} 
              ]
            }
          },
          "inner_hits": { 
            "highlight": {
              "fields": {
                "user.first": {}
              }
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    1.12token_count类型

    token_count用于统计词频:

    
    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "name": { 
              "type": "text",
              "fields": {
                "length": { 
                  "type":     "token_count",
                  "analyzer": "standard"
                }
              }
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    { "name": "John Smith" }
    
    PUT my_index/my_type/2
    { "name": "Rachel Alice Williams" }
    
    GET my_index/_search
    {
      "query": {
        "term": {
          "name.length": 3 
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    1.13 geo point 类型

    地理位置信息类型用于存储地理位置信息的经纬度:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "location": {
              "type": "geo_point"
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "text": "Geo-point as an object",
      "location": { 
        "lat": 41.12,
        "lon": -71.34
      }
    }
    
    PUT my_index/my_type/2
    {
      "text": "Geo-point as a string",
      "location": "41.12,-71.34" 
    }
    
    PUT my_index/my_type/3
    {
      "text": "Geo-point as a geohash",
      "location": "drm3btev3e86" 
    }
    
    PUT my_index/my_type/4
    {
      "text": "Geo-point as an array",
      "location": [ -71.34, 41.12 ] 
    }
    
    GET my_index/_search
    {
      "query": {
        "geo_bounding_box": { 
          "location": {
            "top_left": {
              "lat": 42,
              "lon": -72
            },
            "bottom_right": {
              "lat": 40,
              "lon": -74
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    二、Meta-Fields(元数据)

    2.1 _all

    _all字段是把其它字段拼接在一起的超级字段,所有的字段用空格分开,_all字段会被解析和索引,但是不存储。当你只想返回包含某个关键字的文档但是不明确地搜某个字段的时候就需要使用_all字段。
    例子:

    PUT my_index/blog/1 
    {
      "title":    "Master Java",
      "content":     "learn java",
      "author": "Tom"
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    _all字段包含:[ “Master”, “Java”, “learn”, “Tom” ]

    搜索:

    GET my_index/_search
    {
      "query": {
        "match": {
          "_all": "Java"
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    返回结果:

    {
      "took": 1,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 1,
        "max_score": 0.39063013,
        "hits": [
          {
            "_index": "my_index",
            "_type": "blog",
            "_id": "1",
            "_score": 0.39063013,
            "_source": { "title": "Master Java", "content": "learn java", "author": "Tom" } }
        ]
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    使用copy_to自定义_all字段:

    PUT myindex
    {
      "mappings": {
        "mytype": {
          "properties": {
            "title": {
              "type":    "text",
              "copy_to": "full_content" 
            },
            "content": {
              "type":    "text",
              "copy_to": "full_content" 
            },
            "full_content": {
              "type":    "text"
            }
          }
        }
      }
    }
    
    PUT myindex/mytype/1
    {
      "title": "Master Java",
      "content": "learn Java"
    }
    
    GET myindex/_search
    {
      "query": {
        "match": {
          "full_content": "java"
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.2 _field_names

    _field_names字段用来存储文档中的所有非空字段的名字,这个字段常用于exists查询。例子如下:

    PUT my_index/my_type/1
    {
      "title": "This is a document"
    }
    
    PUT my_index/my_type/2?refresh=true
    {
      "title": "This is another document",
      "body": "This document has a body"
    }
    
    GET my_index/_search
    {
      "query": {
        "terms": {
          "_field_names": [ "body" ] 
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    结果会返回第二条文档,因为第一条文档没有title字段。
    同样,可以使用exists查询:

    GET my_index/_search
    {
        "query": {
            "exists" : { "field" : "body" }
        }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3 _id

    每条被索引的文档都有一个_type和_id字段,_id可以用于term查询、temrs查询、match查询、query_string查询、simple_query_string查询,但是不能用于聚合、脚本和排序。例子如下:

    PUT my_index/my_type/1
    {
      "text": "Document with ID 1"
    }
    
    PUT my_index/my_type/2
    {
      "text": "Document with ID 2"
    }
    
    GET my_index/_search
    {
      "query": {
        "terms": {
          "_id": [ "1", "2" ] 
        }
      }
    }
    
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.4 _index

    多索引查询时,有时候只需要在特地索引名上进行查询,_index字段提供了便利,也就是说可以对索引名进行term查询、terms查询、聚合分析、使用脚本和排序。

    _index是一个虚拟字段,不会真的加到Lucene索引中,对_index进行term、terms查询(也包括match、query_string、simple_query_string),但是不支持prefix、wildcard、regexp和fuzzy查询。

    举例,2个索引2条文档

    
    PUT index_1/my_type/1
    {
      "text": "Document in index 1"
    }
    
    PUT index_2/my_type/2
    {
      "text": "Document in index 2"
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    对索引名做查询、聚合、排序并使用脚本新增字段:

    GET index_1,index_2/_search
    {
      "query": {
        "terms": {
          "_index": ["index_1", "index_2"] 
        }
      },
      "aggs": {
        "indices": {
          "terms": {
            "field": "_index", 
            "size": 10
          }
        }
      },
      "sort": [
        {
          "_index": { 
            "order": "asc"
          }
        }
      ],
      "script_fields": {
        "index_name": {
          "script": {
            "lang": "painless",
            "inline": "doc['_index']" 
          }
        }
      }
    }
    
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    2.4 _meta

    忽略

    2.5 _parent

    _parent用于指定同一索引中文档的父子关系。下面例子中现在mapping中指定文档的父子关系,然后索引父文档,索引子文档时指定父id,最后根据子文档查询父文档。

    PUT my_index
    {
      "mappings": {
        "my_parent": {},
        "my_child": {
          "_parent": {
            "type": "my_parent" 
          }
        }
      }
    }
    
    
    PUT my_index/my_parent/1 
    {
      "text": "This is a parent document"
    }
    
    PUT my_index/my_child/2?parent=1 
    {
      "text": "This is a child document"
    }
    
    PUT my_index/my_child/3?parent=1&refresh=true 
    {
      "text": "This is another child document"
    }
    
    
    GET my_index/my_parent/_search
    {
      "query": {
        "has_child": { 
          "type": "my_child",
          "query": {
            "match": {
              "text": "child document"
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    2.6 _routing

    路由参数,ELasticsearch通过以下公式计算文档应该分到哪个分片上:

    shard_num = hash(_routing) % num_primary_shards
     
    • 1
    • 1

    默认的_routing值是文档的_id或者_parent,通过_routing参数可以设置自定义路由。例如,想把user1发布的博客存储到同一个分片上,索引时指定routing参数,查询时在指定路由上查询:

    PUT my_index/my_type/1?routing=user1&refresh=true 
    {
      "title": "This is a document"
    }
    
    GET my_index/my_type/1?routing=user1
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在查询的时候通过routing参数查询:

    GET my_index/_search
    {
      "query": {
        "terms": {
          "_routing": [ "user1" ] 
        }
      }
    }
    
    GET my_index/_search?routing=user1,user2 
    {
      "query": {
        "match": {
          "title": "document"
        }
      }
    }
    
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在Mapping中指定routing为必须的:

    PUT my_index2
    {
      "mappings": {
        "my_type": {
          "_routing": {
            "required": true 
          }
        }
      }
    }
    
    PUT my_index2/my_type/1 
    {
      "text": "No routing value provided"
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.7 _source

    存储的文档的原始值。默认_source字段是开启的,也可以关闭:

    PUT tweets
    {
      "mappings": {
        "tweet": {
          "_source": {
            "enabled": false
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    但是一般情况下不要关闭,除法你不想做一些操作:

    • 使用update、update_by_query、reindex
    • 使用高亮
    • 数据备份、改变mapping、升级索引
    • 通过原始字段debug查询或者聚合

    2.8 _type

    每条被索引的文档都有一个_type和_id字段,可以根据_type进行查询、聚合、脚本和排序。例子如下:

    PUT my_index/type_1/1
    {
      "text": "Document with type 1"
    }
    
    PUT my_index/type_2/2?refresh=true
    {
      "text": "Document with type 2"
    }
    
    GET my_index/_search
    {
      "query": {
        "terms": {
          "_type": [ "type_1", "type_2" ] 
        }
      },
      "aggs": {
        "types": {
          "terms": {
            "field": "_type", 
            "size": 10
          }
        }
      },
      "sort": [
        {
          "_type": { 
            "order": "desc"
          }
        }
      ],
      "script_fields": {
        "type": {
          "script": {
            "lang": "painless",
            "inline": "doc['_type']" 
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.9 _uid

    _uid和_type和_index的组合。和_type一样,可用于查询、聚合、脚本和排序。例子如下:

    PUT my_index/my_type/1
    {
      "text": "Document with ID 1"
    }
    
    PUT my_index/my_type/2?refresh=true
    {
      "text": "Document with ID 2"
    }
    
    GET my_index/_search
    {
      "query": {
        "terms": {
          "_uid": [ "my_type#1", "my_type#2" ] 
        }
      },
      "aggs": {
        "UIDs": {
          "terms": {
            "field": "_uid", 
            "size": 10
          }
        }
      },
      "sort": [
        {
          "_uid": { 
            "order": "desc"
          }
        }
      ],
      "script_fields": {
        "UID": {
          "script": {
             "lang": "painless",
             "inline": "doc['_uid']" 
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    三、Mapping参数

    3.1 analyzer

    指定分词器(分析器更合理),对索引和查询都有效。如下,指定ik分词的配置:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "content": {
              "type": "text",
              "analyzer": "ik_max_word",
              "search_analyzer": "ik_max_word"
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.2 normalizer

    normalizer用于解析前的标准化配置,比如把所有的字符转化为小写等。例子:

    PUT index
    {
      "settings": {
        "analysis": {
          "normalizer": {
            "my_normalizer": {
              "type": "custom",
              "char_filter": [],
              "filter": ["lowercase", "asciifolding"]
            }
          }
        }
      },
      "mappings": {
        "type": {
          "properties": {
            "foo": {
              "type": "keyword",
              "normalizer": "my_normalizer"
            }
          }
        }
      }
    }
    
    PUT index/type/1
    {
      "foo": "BÀR"
    }
    
    PUT index/type/2
    {
      "foo": "bar"
    }
    
    PUT index/type/3
    {
      "foo": "baz"
    }
    
    POST index/_refresh
    
    GET index/_search
    {
      "query": {
        "match": {
          "foo": "BAR"
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    BÀR经过normalizer过滤以后转换为bar,文档1和文档2会被搜索到。

    3.3 boost

    boost字段用于设置字段的权重,比如,关键字出现在title字段的权重是出现在content字段中权重的2倍,设置mapping如下,其中content字段的默认权重是1.

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "title": {
              "type": "text",
              "boost": 2 
            },
            "content": {
              "type": "text"
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    同样,在查询时指定权重也是一样的:

    POST _search
    {
        "query": {
            "match" : {
                "title": {
                    "query": "quick brown fox",
                    "boost": 2
                }
            }
        }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    推荐在查询时指定boost,第一中在mapping中写死,如果不重新索引文档,权重无法修改,使用查询可以实现同样的效果。

    3.4 coerce

    coerce属性用于清除脏数据,coerce的默认值是true。整型数字5有可能会被写成字符串“5”或者浮点数5.0.coerce属性可以用来清除脏数据:

    • 字符串会被强制转换为整数
    • 浮点数被强制转换为整数
    
    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "number_one": {
              "type": "integer"
            },
            "number_two": {
              "type": "integer",
              "coerce": false
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "number_one": "10" 
    }
    
    PUT my_index/my_type/2
    {
      "number_two": "10" 
    }
    
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    mapping中指定number_one字段是integer类型,虽然插入的数据类型是String,但依然可以插入成功。number_two字段关闭了coerce,因此插入失败。

    3.5 copy_to

    copy_to属性用于配置自定义的_all字段。换言之,就是多个字段可以合并成一个超级字段。比如,first_name和last_name可以合并为full_name字段。

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "first_name": {
              "type": "text",
              "copy_to": "full_name" 
            },
            "last_name": {
              "type": "text",
              "copy_to": "full_name" 
            },
            "full_name": {
              "type": "text"
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "first_name": "John",
      "last_name": "Smith"
    }
    
    GET my_index/_search
    {
      "query": {
        "match": {
          "full_name": { 
            "query": "John Smith",
            "operator": "and"
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    3.6 doc_values

    doc_values是为了加快排序、聚合操作,在建立倒排索引的时候,额外增加一个列式存储映射,是一个空间换时间的做法。默认是开启的,对于确定不需要聚合或者排序的字段可以关闭。

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "status_code": { 
              "type":       "keyword"
            },
            "session_id": { 
              "type":       "keyword",
              "doc_values": false
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注:text类型不支持doc_values。

    3.7 dynamic

    dynamic属性用于检测新发现的字段,有三个取值:

    • true:新发现的字段添加到映射中。(默认)
    • flase:新检测的字段被忽略。必须显式添加新字段。
    • strict:如果检测到新字段,就会引发异常并拒绝文档。

    例子:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "dynamic": false, 
          "properties": {
            "user": { 
              "properties": {
                "name": {
                  "type": "text"
                },
                "social_networks": { 
                  "dynamic": true,
                  "properties": {}
                }
              }
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    PS:取值为strict,非布尔值要加引号。

    3.8 enabled

    ELasticseaech默认会索引所有的字段,enabled设为false的字段,es会跳过字段内容,该字段只能从_source中获取,但是不可搜。而且字段可以是任意类型。

    PUT my_index
    {
      "mappings": {
        "session": {
          "properties": {
            "user_id": {
              "type":  "keyword"
            },
            "last_updated": {
              "type": "date"
            },
            "session_data": { 
              "enabled": false
            }
          }
        }
      }
    }
    
    PUT my_index/session/session_1
    {
      "user_id": "kimchy",
      "session_data": { 
        "arbitrary_object": {
          "some_array": [ "foo", "bar", { "baz": 2 } ]
        }
      },
      "last_updated": "2015-12-06T18:20:22"
    }
    
    PUT my_index/session/session_2
    {
      "user_id": "jpountz",
      "session_data": "none", 
      "last_updated": "2015-12-06T18:22:13"
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    3.9 fielddata

    搜索要解决的问题是“包含查询关键词的文档有哪些?”,聚合恰恰相反,聚合要解决的问题是“文档包含哪些词项”,大多数字段再索引时生成doc_values,但是text字段不支持doc_values。

    取而代之,text字段在查询时会生成一个fielddata的数据结构,fielddata在字段首次被聚合、排序、或者使用脚本的时候生成。ELasticsearch通过读取磁盘上的倒排记录表重新生成文档词项关系,最后在Java堆内存中排序。

    text字段的fielddata属性默认是关闭的,开启fielddata非常消耗内存。在你开启text字段以前,想清楚为什么要在text类型的字段上做聚合、排序操作。大多数情况下这么做是没有意义的。

    “New York”会被分析成“new”和“york”,在text类型上聚合会分成“new”和“york”2个桶,也许你需要的是一个“New York”。这是可以加一个不分析的keyword字段:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "my_field": { 
              "type": "text",
              "fields": {
                "keyword": { 
                  "type": "keyword"
                }
              }
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    上面的mapping中实现了通过my_field字段做全文搜索,my_field.keyword做聚合、排序和使用脚本。

    3.10 format

    format属性主要用于格式化日期:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "date": {
              "type":   "date",
              "format": "yyyy-MM-dd"
            }
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    更多内置的日期格式:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html

    3.11 ignore_above

    ignore_above用于指定字段索引和存储的长度最大值,超过最大值的会被忽略:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "message": {
              "type": "keyword",
              "ignore_above": 15
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1 
    {
      "message": "Syntax error"
    }
    
    PUT my_index/my_type/2 
    {
      "message": "Syntax error with some long stacktrace"
    }
    
    GET my_index/_search 
    {
      "size": 0, 
      "aggs": {
        "messages": {
          "terms": {
            "field": "message"
          }
        }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    mapping中指定了ignore_above字段的最大长度为15,第一个文档的字段长小于15,因此索引成功,第二个超过15,因此不索引,返回结果只有”Syntax error”,结果如下:

    {
      "took": 2,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 2,
        "max_score": 0,
        "hits": []
      },
      "aggregations": {
        "messages": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [] }
      }
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    展开全文
  • 1. 安装RPLIDAR包 建立catkin工作空间,在其src目录下git包: git clone ... 返回工作空间 catkin_make编译 ...2. 下载安装hector_mapping sudo apt-get install ros-indigo-hector-slam 3. 在rpli
  • 制造商提供的产品列表将由团队进行分类,鉴于给定列表中可能有超过100,000个订单项,因此这是一项非常繁琐的任务。 我建议创建一个程序来帮助解决这个问题。 它包含两个部分-用于创建模板映射的Java和用于实际分配...
  • Elasticsearch 5.4 Mapping详解

    万次阅读 多人点赞 2017-06-12 14:22:13
    text取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于...
  • Surveying and Mapping核心期刊 测绘科学与技术(Surveying and Mapping)下设大地测量学与测量工程、摄影测量与遥感、地图制图学与地理信息工程三个研究方向。 Survering and Mapping核心期刊为我们介绍GIS、RS和...
  • Mapping就是ES数据字段的元数据,ES在创建索引的时候dynamic mapping会自动为不同的数据指定对应的 mappingmapping 中包含了字段的类型、搜索方式(exact value或者full text)、分词器等。可以使用GET /index_...
  •  Easydb,是一款简洁易用的O/R Mapping产品,是应用于JAVA/J2EE项目中的持久层框架,使得开发人员可以更加高效地构建应用系统,着重关注业务逻辑而非数据存储,节省项目的开发、维护成本。  Easydb,其思路基于我...
  • ElasticSearch7.4的数据类型,Mapping Type, 指定索引Document的Mapping Type 基础数据类型:(ELasticsearch 5.X之后的字段类型不再支持string,由text或keyword取代) 一、字符串 1.1 文本类型 text 当一个...
  • Cookie mapping技术

    万次阅读 2013-09-04 11:48:48
    摘要:Cookie mapping分为两步:(1)google ad exchange等在网站主网站上种cookie,生成google_id (2)用户在网站主网站上浏览时,有广告请求; google把请求302重定向到dsp,并携带加密过后的google_nid。这样dsp就...
  • 简述ToneMapping发展史

    千次阅读 2019-03-06 14:39:20
    简述ToneMapping发展史HDR2002年Reinhard ToneMapping2007年CryEngine22010年Uncharted2(神秘海域2)公开算法目前最好的ToneMapping算法---来自学术界的藐视,Academy Color Encoding System(ACES) HDR 为什么会...
  • 一共出现过两次类似的错误,其一是: Could not set parameters for mapping: ParameterMapping{property='id',其二是: Could not set parameters for mapping: ParameterMapping{property='time', 解决方案 两个bug...
  • Mapping简介 mapping 是用来定义文档及其字段的存储方式、索引方式的手段,例如利用mapping来定义以下内容: 哪些字段需要被定义为全文检索类型 哪些字段包含number、date类型等 格式化时间格式 自定义规则,...
  • ES的mapping配置详解

    千次阅读 2020-05-22 09:35:47
    mapping配置 mapping的基本格式 { "mappings":{ "_doc":{ "_all":{ "enabled":false }, "properties":{ "uuid":{ "type":"text", "copy_to":"_hippo_all
  • Elasticsearch mapping field修改过程

    千次阅读 2018-04-16 11:04:03
    Elasticsearch 的坑爹事 本文记录一次Elasticsearch mapping field修改过程团队使用Elasticsearch做日志的分类检索分析服务,使用了类似如下的_mapping1234567891011121314{ "settings" : { "...
  • O/R Mapping

    2012-04-22 07:34:00
    什么是O/R Mapping? ORM,即Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它...
  • OR Mapping 的原理

    千次阅读 2013-12-29 17:25:48
    OR-Mapping是面向对象分析设计的产物,主要解决对象层次的映射、对象关系的映射以及对象的持久化问题,也是分层设计要解决的问题之一。OR-Mapping会给程序设计带来那些好处呢?在面向对象的分层设计的系统体系中,...
  • 什么是Mapping我们知道,es如果对应数据表,表中的数据是不是有数据类型,那么es的mapping就是来设置这个字段类型的。它的主要作用:定义字段名称定义字段的数据类型,例如字符串、数值等字段 倒排索引的相关配置,...
  • Mapping_Earthquakes-源码

    2021-04-05 07:56:46
    最终产品是一个显示地震信息的网站。 ![map_1.png](https:// ) 资源 实用工具:VSCode,Javascript,CSS,HTML,GeoJSON数据 ![map_2.png](https:// ) 结果 该网站的主要功能包括在不同版本的地图之间...
  • Object Relational Mapping

    2007-03-20 11:16:00
    ORM对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久...
  • 在RTB(实时竞价广告,Real-Time-Bidding)广告领域(当然实际上不仅仅是这个领域),有一个常见的词汇叫 Cookie Mapping(Cookie 匹配),一会又是DSP(需求方供应平台)与DSP的Cookie Mapping,一会又是DSP与Ad ...
  • 什么是OR Mapping

    千次阅读 2013-11-03 22:11:59
    对象-关系映射(ORM, 即 Object-Relation Mapping)模式指的是在单个组件中负责所有实体域对象的持久化,封装数据访问细节。ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象-关系的映射细节,...
  • 手动来为es创建index的mapping是非常重要的,需要每个field来进行分析,设置其参数,这样一方面可以节省存储空间,另一方面也可以由于字段设置不合理,导致需要重建索引这类昂贵的操作。 参考官网:把elastic ...
  • ES Mapping、字段类型Field type详解

    万次阅读 多人点赞 2018-10-15 15:02:18
    text取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于...
  • 关于OR-Mapping的学习心得体会 注:本文只针对设计上采用OOA(面向对象分析)及OOD(面向对象设计)方式,数据存储采用关系型数据库的系统而言。 从对OR-Mapping错误认识谈起 从工作流管理系统和信息共享平台的设计...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,284
精华内容 14,913
关键字:

产品mapping