ES数据建模最佳实践

什么是数据建模

数据建模是对真实世界进行描述的一种工具和方法,实现对现实世界的映射

建模三过程

建模考虑点

功能需求

  • 是否需要被搜索
  • 是否需要聚合

性能需求

  • 主分片数
  • 字段是否需要存储在磁盘上

如何对字段进行建模

字段类型

  • Text
    • 全文搜索
    • 默认不支持聚合分析及排序。需要设置 fielddata 为true 支持
  • Keyword
    • 用户ID、枚举 及 不需要分词的文本。如:电话号码、email、邮政编码、性别等
    • 使用于 Filter, Sorting 及 Aggregations
  • 多字段类型
    • 文本默认设置成Text,并设置子字段 keyword
    • 处理人类语言时,通过增加 英文、拼音、标准分词器,提高搜索结果
  • 数值类型
    • 尽量选择贴近的类型。如可以用 byte, 就不要用 long
  • 枚举类型
    • 设置keyword。即便是数字,也应该设置成 keyword,获取更好的性能

搜索

  • 如果不需要检索、排序及聚合分析
    • enable 设置成 false
  • 如果不需要检索
    • index 设置成 false

聚合及排序

  • 如果不需要检索、排序及聚合分析
    • enable 设置成 false
  • 如不需要排序或者聚合分析,
    • doc_values / fielddata 设置为 false
  • 更新频繁,聚合查询频繁的 keyword 类型的字段
    • 推荐将 eager_global_ordinals 设置为 true

存储

  • store 设置为 true,可以存储该字段的原始数据
  • 一般结合 _source 的 enabled 为 false 时使用
  • _source 的enabled设置为false后,字段无法最 reindex,无法做 update。该设置需要慎重

最佳实践

Dynamic 避免过多字段

ES 默认开启 Dynamic,可选值如下:

  • true 未知字段自动加入
  • false 新字段不会被索引,但是会保存在 _source
  • strict 新字段不会被索引,文档写入失败

在 Dynamic开启的情况下,可能会导致数据字段膨胀。避免导致字段膨胀的可选方法如下:

###### Cookie Service

##索引数据,dynamic mapping 会不断加入新增字段
PUT cookie_service/_doc/1
{
 "url":"www.google.com",
 "cookies":{
   "username":"tom",
   "age":32
 }
}

PUT cookie_service/_doc/2
{
 "url":"www.amazon.com",
 "cookies":{
   "login":"2019-01-01",
   "email":"xyz@abc.com"
 }
}


DELETE cookie_service
#使用 Nested 对象,增加key/value
PUT cookie_service
{
  "mappings": {
    "properties": {
      "cookies": {
        "type": "nested",
        "properties": {
          "name": {
            "type": "keyword"
          },
          "dateValue": {
            "type": "date"
          },
          "keywordValue": {
            "type": "keyword"
          },
          "IntValue": {
            "type": "integer"
          }
        }
      },
      "url": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}


##写入数据,使用key和合适类型的value字段
PUT cookie_service/_doc/1
{
 "url":"www.google.com",
 "cookies":[
    {
      "name":"username",
      "keywordValue":"tom"
    },
    {
       "name":"age",
      "intValue":32
    }
   ]
 }


PUT cookie_service/_doc/2
{
 "url":"www.amazon.com",
 "cookies":[
    {
      "name":"login",
      "dateValue":"2019-01-01"
    },
    {
       "name":"email",
      "keywordValue":"test@test.com"
    }
   ]
 }

# Nested 查询,通过bool查询进行过滤
POST cookie_service/_search
{
  "query": {
    "nested": {
      "path": "cookies",
      "query": {
        "bool": {
          "filter": [
            {
            "term": {
              "cookies.name": "age"
            }},
            {
              "range":{
                "cookies.intValue":{
                  "gte":30
                }
              }
            }
          ]
        }
      }
    }
  }
}

上述Demo为何使用 Nested原因可查看 此博客

避免wildcard查询

可以直接利用 ingest 或者 分词 等技术,避免使用 wildcard

其他

  • Filter Context 可以避免算分,并且可利用缓存。Bool查询中Filter 和 Must Not都属于Filter Context
  • Index Template
  • Dynamic Template
  • Index Alias
  • Update By Query & Reindex

Demo

# Index 一本书的信息
PUT books/_doc/1
{
  "title":"Mastering ElasticSearch 5.0",
  "description":"Master the searching, indexing, and aggregation features in ElasticSearch Improve users’ search experience with Elasticsearch’s functionalities and develop your own Elasticsearch plugins",
  "author":"Bharvi Dixit",
  "public_date":"2017",
  "cover_url":"https://images-na.ssl-images-amazon.com/images/I/51OeaMFxcML.jpg"
}



#查询自动创建的Mapping
GET books/_mapping

DELETE books

#优化字段类型
PUT books
{
      "mappings" : {
      "properties" : {
        "author" : {"type" : "keyword"},
        "cover_url" : {"type" : "keyword","index": false},
        "description" : {"type" : "text"},
        "public_date" : {"type" : "date"},
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 100
            }
          }
        }
      }
    }
}

#Cover URL index 设置成false,无法对该字段进行搜索
POST books/_search
{
  "query": {
    "term": {
      "cover_url": {
        "value": "https://images-na.ssl-images-amazon.com/images/I/51OeaMFxcML.jpg"
      }
    }
  }
}

#Cover URL index 设置成false,依然支持聚合分析
POST books/_search
{
  "aggs": {
    "cover": {
      "terms": {
        "field": "cover_url",
        "size": 10
      }
    }
  }
}


DELETE books
#新增 Content字段。数据量很大。选择将Source 关闭
PUT books
{
      "mappings" : {
      "_source": {"enabled": false},
      "properties" : {
        "author" : {"type" : "keyword","store": true},
        "cover_url" : {"type" : "keyword","index": false,"store": true},
        "description" : {"type" : "text","store": true},
         "content" : {"type" : "text","store": true},
        "public_date" : {"type" : "date","store": true},
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 100
            }
          },
          "store": true
        }
      }
    }
}


# Index 一本书的信息,包含Content
PUT books/_doc/1
{
  "title":"Mastering ElasticSearch 5.0",
  "description":"Master the searching, indexing, and aggregation features in ElasticSearch Improve users’ search experience with Elasticsearch’s functionalities and develop your own Elasticsearch plugins",
  "content":"The content of the book......Indexing data, aggregation, searching.    something else. something in the way............",
  "author":"Bharvi Dixit",
  "public_date":"2017",
  "cover_url":"https://images-na.ssl-images-amazon.com/images/I/51OeaMFxcML.jpg"
}

#查询结果中,Source不包含数据
POST books/_search
{}

#搜索,通过store 字段显示数据,同时高亮显示 conent的内容
POST books/_search
{
  "stored_fields": ["title","author","public_date"],
  "query": {
    "match": {
      "content": "searching"
    }
  },

  "highlight": {
    "fields": {
      "content":{}
    }
  }

}

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值