Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >elasticsearch中mapping全解实战

elasticsearch中mapping全解实战

作者头像
海向
发布于 2019-12-17 10:52:39
发布于 2019-12-17 10:52:39
1.2K00
代码可运行
举报
文章被收录于专栏:海向海向
运行总次数:0
代码可运行

?原文地址为https://cloud.tencent.com/developer/article/1555004,转载请注明出处!

?es与java的整合以及常用CRUD、搜索API已被作者封装,开箱即用效果很好,欢迎star谢谢!github

Mapping简介

mapping 是用来定义文档及其字段的存储方式、索引方式的手段,例如利用mapping 来定义以下内容:

  • 哪些字段需要被定义为全文检索类型
  • 哪些字段包含numberdate类型等
  • 格式化时间格式
  • 自定义规则,用于控制动态添加字段的映射

Mapping Type

每个索引都拥有唯一的 mapping type,用来决定文档将如何被索引。mapping type由下面两部分组成

  • Meta-fields 元字段用于自定义如何处理文档的相关元数据。 元字段的示例包括文档的_index,_type,_id和_source字段。
  • Fields or properties 映射类型包含与文档相关的字段或属性的列表。

分词器最佳实践

因为后续的keywordtext设计分词问题,这里给出分词最佳实践。即索引时用ik_max_word,搜索时分词器用ik_smart,这样索引时最大化的将内容分词,搜索时更精确的搜索到想要的结果。

例如我想搜索的是小米手机,我此时的想法是想搜索出小米手机的商品,而不是小米音响、小米洗衣机等其他产品,也就是说商品信息中必须只有华为手机这个词。

我们后续会使用"search_analyzer": "ik_smart"来实现这样的需求。

字段类型

  • 一种简单的数据类型,例如textkeyworddoublebooleanlongdateip类型。
  • 也可以是一种分层的json对象(支持属性嵌套)。
  • 也可以是一些不常用的特殊类型,例如geo_pointgeo_shapecompletion

针对同一字段支持多种字段类型可以更好地满足我们的搜索需求,例如一个string类型的字段可以设置为text来支持全文检索,与此同时也可以让这个字段拥有keyword类型来做排序和聚合,另外我们也可以为字段单独配置分词方式,例如"analyzer": "ik_max_word",

text 类型

text类型的字段用来做全文检索,例如邮件的主题、淘宝京东中商品的描述等。这种字段在被索引存储前先进行分词,存储的是分词后的结果,而不是完整的字段。text字段不适合做排序和聚合。如果是一些结构化字段,分词后无意义的字段建议使用keyword类型,例如邮箱地址、主机名、商品标签等。

常有参数包含以下

  • analyzer:用来分词,包含索引存储阶段搜索阶段(其中查询阶段可以被search_analyzer参数覆盖),该参数默认设置为index的analyzer设置或者standard analyzer
  • index:是否可以被搜索到。默认是true
  • fields:Multi-fields允许同一个字符串值同时被不同的方式索引,例如用不同的analyzer使一个field用来排序和聚类,另一个同样的string用来分析和全文检索。下面会做详细的说明
  • search_analyzer:这个字段用来指定搜索阶段时使用的分词器,默认使用analyzer的设置
  • search_quote_analyzer:搜索遇到短语时使用的分词器,默认使用search_analyzer的设置

keyword 类型

keyword用于索引结构化内容(例如电子邮件地址,主机名,状态代码,邮政编码或标签)的字段,这些字段被拆分后不具有意义,所以在es中应索引完整的字段,而不是分词后的结果。

通常用于过滤(例如在博客中根据发布状态来查询所有已发布文章),排序和聚合。keyword只能按照字段精确搜索,例如根据文章id查询文章详情。如果想根据本字段进行全文检索相关词汇,可以使用text类型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT my_index
{
  "mappings": {
    "properties": {
      "tags": {
        "type":  "keyword"
      }
    }
  }
}
  • index:是否可以被搜索到。默认是true
  • fields:Multi-fields允许同一个字符串值同时被不同的方式索引,例如用不同的analyzer使一个field用来排序和聚类,另一个同样的string用来分析和全文检索。下面会做详细的说明
  • null_value:如果该字段为空,设置的默认值,默认为null
  • ignore_above:设置索引字段大小的阈值。该字段不会索引大小超过该属性设置的值,默认为2147483647,代表着可以接收任意大小的值。但是这一值可以被PUT Mapping Api中新设置的ignore_above来覆盖这一值。

date类型

支持排序,且可以通过format字段对时间格式进行格式化。

json中没有时间类型,所以在es在规定可以是以下的形式:

  • 一段格式化的字符串,例如"2015-01-01"或者"2015/01/01 12:10:30"
  • 一段long类型的数字,指距某个时间的毫秒数,例如1420070400001
  • 一段integer类型的数字,指距某个时间的秒数

object类型

mapping中不用特意指定field为object类型,因为这是它的默认类型。

json类型天生具有层级的概念,文档内部还可以包含object类型进行嵌套。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT my_index/_doc/1
{ 
  "region": "US",
  "manager": { 
    "age":     30,
    "name": { 
      "first": "John",
      "last":  "Smith"
    }
  }
}

在es中上述对象会被按照以下的形式进行索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "region":             "US",
  "manager.age":        30,
  "manager.name.first": "John",
  "manager.name.last":  "Smith"
}

mapping可以对不同字段进行不同的设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT my_index
{
  "mappings": {
    "properties": { 
      "region": {
        "type": "keyword"
      },
      "manager": { 
        "properties": {
          "age":  { "type": "integer" },
          "name": { 
            "properties": {
              "first": { "type": "text" },
              "last":  { "type": "text" }
            }
          }
        }
      }
    }
  }
}

nest类型

nest类型是一种特殊的object类型,它允许object可以以数组形式被索引,而且数组中的某一项都可以被独立检索。

而且es中没有内部类的概念,而是通过简单的列表来实现nest效果,例如下列结构的文档:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT my_index/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

上面格式的对象会被按照下列格式进行索引,因此会发现一个user中的两个属性值不再匹配,alicewhite失去了联系

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

range类型

支持以下范围类型:

类型

范围

integer_range

-2的31次 到 2的31次-1.

float_range

32位单精度浮点数

long_range

-2的63次 到 2的63次-1.

double_range

64位双精度浮点数

date_range

unsigned 64-bit integer milliseconds

ip_range

ipv4和ipv6或者两者的混合

使用范例为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT range_index
{
  "settings": {
    "number_of_shards": 2
  },
  "mappings": {
    "properties": {
      "age_range": {
        "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
{
  "age_range" : { 
    "gte" : 10,
    "lte" : 20
  },
  "time_frame" : { 
    "gte" : "2015-10-31 12:00:00", 
    "lte" : "2015-11-01"
  }
}

实战:同时使用keyword和text类型

注:term是查询时对关键字不分词,keyword是索引时不分词

上述我们讲解过keywordtext一个不分词索引,一个是分词后索引,我们利用他们的fields属性来让当前字段同时具备keywordtext类型。

首先我们创建索引并指定mapping,为title同时设置keywordtext属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT /idx_item/
{
  "settings": {
    "index": {
        "number_of_shards" : "2",
        "number_of_replicas" : "0"
    }
  },
  "mappings": {
    "properties": {
      "itemId" : {
        "type": "keyword",
        "ignore_above": 64
      },
      "title" : {
        "type": "text",
        "analyzer": "ik_max_word", 
        "search_analyzer": "ik_smart", 
        "fields": {
          "keyword" : {"ignore_above" : 256, "type" : "keyword"}
        }
      },
      "desc" : {"type": "text", "analyzer": "ik_max_word"},
      "num" : {"type": "integer"},
      "price" : {"type": "long"}
    }
  }
}

我们已经往es中插入以下数据

_index

_type

_id

_score

itemId

title

desc

num

Price

idx_item

_doc

rvsX-W4Bo-iJGWqbQ8dk

1

1

苏泊尔煮饭SL3200

让煮饭更简单,让生活更快乐

100

200

idx_item

_doc

sPsY-W4Bo-iJGWqbscfU

1

3

厨房能手威猛先生

你煲粥,我洗锅

100

30

idx_item

_doc

r_sX-W4Bo-iJGWqbhMew

1

2

苏泊尔煲粥好能手型号SL322

你煲粥,我煲粥,我们一起让煲粥更简单

100

190

title=”苏泊尔煮饭SL3200“ 根据text以及最细粒度分词设置"analyzer": "ik_max_word",在es中按照以下形式进行索引存储

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{ "苏泊尔","煮饭", "sl3200", "sl","3200"}

title.keyword=”苏泊尔煮饭SL3200因为不分词,所以在es中索引存储形式为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
苏泊尔煮饭SL3200

我们首先对title.keyword进行搜索,只能搜索到第一条数据,因为match搜索会将关键字分词然后去搜索,分词后的结果包含"苏泊尔煮饭SL3200"所以搜索成功,我们将搜索关键字改为苏泊尔煮饭等都不会查到数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET idx_item/_search
{
  "query": {
    "bool": {
      "must": {
        "match": {"title.keyword": "苏泊尔煮饭SL3200"}
        }
    }
  }
}

我们改用term搜索,他搜索不会分词,正好与es中的数据精准匹配,也只有第一条数据,我们将搜索关键字改为苏泊尔煮饭等都不会查到数据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET idx_item/_search
{
  "query": {
    "bool": {
      "must": {
        "term": {"title.keyword": "苏泊尔煮饭SL3200"}
        }
    }
  }
}

我们继续对title使用match进行查询,结果查到了第一条和第三条数据,因为它们在es中被索引的数据包含苏泊尔关键字

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET idx_item/_search
{
  "query": {
    "bool": {
      "must": {"match": {"title": "苏泊尔"}
        }
    }
  }
}

我们如果搜索苏泊尔煮饭SL3200会发现没有返回数据,因为title在索引时没有苏泊尔煮饭SL3200这一项,而term时搜索关键字也不分词,所以无法匹配到数据。但是我们将内容改为苏泊尔时,就可以搜索到第一条和第三条内容,因为第一条和第三条的title被分词后的索引包含苏泊尔字段,所以可以查出第一三条。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"term": {"title": "苏泊尔煮饭SL3200"}

实战:格式化时间、以及按照时间排序

我们创建索引idx_pro,将mytimestampcreateTime字段分别格式化成两种时间格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PUT /idx_pro/
{
  "settings": {
    "index": {
        "number_of_shards" : "2",
        "number_of_replicas" : "0"
    }
  },
  "mappings": {
    "properties": {
      "proId" : {
        "type": "keyword",
        "ignore_above": 64
      },
      "name" : {
        "type": "text",
        "analyzer": "ik_max_word", 
        "search_analyzer": "ik_smart", 
        "fields": {
          "keyword" : {"ignore_above" : 256, "type" : "keyword"}
        }
      },
      "mytimestamp" : {
        "type": "date",
        "format": "epoch_millis"
      },
      "createTime" : {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      }
    }
  }
}

插入四组样本数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
POST idx_pro/_doc
{
  "proId" : "1",
  "name" : "冬日工装裤",
  "timestamp" : 1576312053946,
  "createTime" : "2019-12-12 12:56:56"
}
POST idx_pro/_doc
{
  "proId" : "2",
  "name" : "冬日羽绒服",
  "timestamp" : 1576313210024,
  "createTime" : "2019-12-10 10:50:50"
}
POST idx_pro/_doc
{
  "proId" : "3",
  "name" : "花花公子外套",
  "timestamp" : 1576313239816,
  "createTime" : "2019-12-19 12:50:50"
}
POST idx_pro/_doc
{
  "proId" : "4",
  "name" : "花花公子羽绒服",
  "timestamp" : 1576313264391,
  "createTime" : "2019-12-12 11:56:56"
}

我们可以使用sort参数来进行排序,并且支持数组形式,即同时使用多字段排序,只要改为[]就行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET idx_pro/_search
{
  "sort":{"createTime": {"order": "asc"}}, 
  "query": {
    "bool": {
      "must": {"match_all": {}}
    }
  }
}

我们也可以使用range参数来搜索指定时间范围内的数据,当然range也支持integerlong等类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET idx_pro/_search
{
  "query": {
    "bool": {
      "must": {
        "range": {
          "timestamp": {
            "gt": "1576313210024",
            "lt": "1576313264391"
          }
        }
      }
    }
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用elasticsearch搭建自己的搜索系统
?es搜索系统封装源码,走过路过,请帮我点个star哦! ?原文地址为https://www.cnblogs.com/haixiang/p/12451703.html,转载请注明出处! 什么是ela
海向
2020/05/12
1.2K0
使用 Elasticsearch 搭建自己的搜索系统,真心强大!
点击关注公众号,Java干货及时送达 作者:Hai Xiang 来源:www.cnblogs.com/haixiang/p/12867160.html 什么是elasticsearch Elasticsearch 是一个开源的高度可扩展的全文搜索和分析引擎,拥有查询近实时的超强性能。 大名鼎鼎的Lucene 搜索引擎被广泛用于搜索领域,但是操作复杂繁琐,总是让开发者敬而远之。而 Elasticsearch将 Lucene 作为其核心来实现所有索引和搜索的功能,通过简单的 RESTful 语法来隐藏掉 L
Java技术栈
2022/06/14
1.3K0
使用 Elasticsearch 搭建自己的搜索系统,真心强大!
Elasticsearch搜索查询语法
原文地址为https://www.cnblogs.com/haixiang/p/12095578.html,转载请注明出处! es与SpringBoot的整合以及常用CRUD、搜索API已被作者封装,开箱即用效果很好,欢迎star谢谢!github
海向
2019/12/26
1.3K0
【Elasticsearch系列十六】Mapping 映射
概念:自动或手动为 index 中的_doc 建立的一种数据结构和相关配置,简称为 mapping 映射。
kwan的解忧杂货铺
2024/09/21
1340
Elasticsearch Mapping
Elasticsearch Mapping用于定义文档。比如:文档所拥有的字段、文档中每个字段的数据类型、哪些字段需要进行索引等。本文将先后从mapping type、mapping parameter、mapping field和mapping explosion这四个维度展开。
程序猿杜小头
2022/12/01
8980
学好Elasticsearch系列-Mapping
这篇讲解Elasticsearch中非常重要的一个概念Mapping,Mapping是索引必不可少的组成部分。
BookSea
2023/07/26
3710
学好Elasticsearch系列-Mapping
干货 | Elasticsearch 索引设计实战指南
随着 Elastic 的上市,ELK Stack 不仅在 BAT 的大公司得到长足的发展,而且在各个中小公司都得到非常广泛的应用,甚至连“婚庆网站”都开始使用 Elasticsearch 了。随之而来的是 Elasticsearch 相关部署、框架、性能优化的文章早已铺天盖地。
铭毅天下
2020/02/20
10.3K0
ElasticSearch系列18:Mapping 设计指南
ElasticSearch 的 mapping 该如何设计,才能保证检索的高效?想要回答这个问题,就需要全面系统地掌握 mapping 各种参数的含义以及其适用的场景。(ps:本文基于ElasticSearch 7.7.1)
方才编程_公众号同名
2020/11/13
1.6K0
ElasticSearch系列18:Mapping 设计指南
Elasticsearch学习(五)Elasticsearch中的mapping问题,Search 搜索详解
Mapping在Elasticsearch中是非常重要的一个概念。决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段等。
一写代码就开心
2021/03/02
1.8K0
Elasticsearch学习(五)Elasticsearch中的mapping问题,Search 搜索详解
ElasticSearch 6.x 学习笔记:14.mapping参数
官方文档 https://www.elastic.co/guide/en/elasticsearch/reference/6.1/mapping-params.html ElasticSearch提供了丰富的映射参数对字段的映射进行参数设计,比如字段的分词器、字段权重、日期格式、检索模型等等。
程裕强
2022/05/06
1.3K0
[Elasticsearch] ES 的Mapping 设计在实际场景中应用
项目中有个需求是需要几个字段作为标签,统计各个标签的文档数量,同时支持分词后的全文检索功能。
awwewwbbb
2021/12/27
6800
一起学 Elasticsearch 系列 -Mapping
本篇讲解Elasticsearch中非常重要的一个概念:Mapping,Mapping是索引必不可少的组成部分。
BookSea
2023/11/13
4650
一起学 Elasticsearch 系列 -Mapping
Elasticsearch全文检索实战小结——复盘我带的第二个项目
一、项目概述 这是一个被我称之为“没有枪、没有炮,硬着头皮自己造”的项目。项目是和其它公司合作的三个核心模块开发。 使用ES的目的是: 1)、采集数据、网站数据清洗后存入ES; 2)、对外提供精
铭毅天下
2018/03/20
2.8K0
Elasticsearch全文检索实战小结——复盘我带的第二个项目
干货 | Elasticsearch 检索类型选型指南
以 Elasticsearch 8.1 官方文档为例,检索分类不会也不可能超出这个范围。
铭毅天下
2022/05/23
1.2K0
干货 | Elasticsearch 检索类型选型指南
Web基础配置篇(十二): Elasticsearch的安装配置及入门使用
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。
品茗IT
2019/09/12
6460
【Elasticsearch系列九】控制台实战
类比 sql: select * from book where name like ’ %java%’ order by price desc
kwan的解忧杂货铺
2024/09/17
970
Elasticsearch搜索特性
方案一、可以是用wildcard通配符,但是要设置不分词,这种方案性能不好 方案二、可以使用ngram分词器 “min_gram”: 2,”max_gram”: 3 单词假设是 abcde0001 ab bc cd abc cde 001.。。。等等 被分词2个字母一组和3个字符一组。。、。
丁D
2022/08/12
7650
Elasticsearch 重要mapping参数详解(三)
我们先来看一下一些常用的参数的简介,大致明白这些参数的含义,后面会对一些重要的参数做一个更加详细一些的说明。
问道白发
2019/12/15
6.8K2
Elasticsearch 重要mapping参数详解(三)
Springboot2.x整合ElasticSearch7.x实战(三)
还没开始的同学,建议先读一下系列攻略目录:Springboot2.x整合ElasticSearch7.x实战目录
JavaPub
2021/01/10
3.6K1
Springboot2.x整合ElasticSearch7.x实战(三)
Elasticsearch从入门到放弃:瞎说Mapping
前面我们聊了 Elasticsearch 的索引、搜索和分词器,今天再来聊另一个基础内容—— Mapping。
Jackeyzhe
2020/08/05
9620
推荐阅读
相关推荐
使用elasticsearch搭建自己的搜索系统
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验