关联字段类型应用

join父子关系

  • 概念定义:

数据存在父子关系
一条数据可以有多条子数据
一条子数据仅有一条父数据

  • 优点:

数据更新分离影响

  • 注意事项:

父子数据必须在同一分片上
父子层级深度要注意
一个索引仅容许一对父子关系约束
一个父关系可以支持多个字对应关系

定义类型和join索引:

定义join关系为order_join,其中order是父文档,suborder是子文档。

  1. DELETE myorder
  2. PUT myorder
  3. {
  4. "mappings": {
  5. "properties": {
  6. "order_join": {
  7. "type": "join",
  8. "relations":{
  9. "order": "suborder"
  10. }
  11. }
  12. }
  13. }
  14. }

创建mapping

  1. PUT myorder/_mapping
  2. {
  3. "properties": {
  4. "orderId": {
  5. "type": "keyword"
  6. },
  7. "shortTime": {
  8. "type": "date"
  9. },
  10. "name": {
  11. "type": "keyword"
  12. },
  13. "amount": {
  14. "type": "double"
  15. },
  16. "desc": {
  17. "type": "text"
  18. }
  19. }
  20. }

插入主单数据:

order_join定义为order类型

  1. PUT myorder/_doc/10001
  2. {
  3. "shortTime": "2019-01-05",
  4. "orderId": "10001",
  5. "name": "user2",
  6. "amount": 123.09,
  7. "desc": "其他收入",
  8. "order_join": "order"
  9. }

插入子单数据


建立父子关系索引,routing 参数是必须的,因为父子文档必须在同一个分片上

  1. POST myorder/_doc?routing=1
  2. {
  3. "shortTime": "2019-01-05",
  4. "orderId": "10001",
  5. "name": "user2",
  6. "amount": 12.09,
  7. "desc": "收入",
  8. "order_join": {
  9. "name": "suborder",
  10. "parent":"10001"
  11. }
  12. }
  13. POST myorder/_doc?routing=1
  14. {
  15. "shortTime": "2019-01-05",
  16. "orderId": "10002",
  17. "name": "user2",
  18. "amount": 122.09,
  19. "desc": "收入",
  20. "order_join": {
  21. "name": "suborder",
  22. "parent":"10001"
  23. }
  24. }

查询主单:

  1. GET myorder/_search
  2. {
  3. "query": {
  4. "has_child" : {
  5. "type" : "suborder",
  6. "query" : {
  7. "match_all" : {
  8. }
  9. }
  10. }
  11. }
  12. }

查询子单:

  1. GET myorder/_search
  2. {
  3. "query": {
  4. "has_parent" : {
  5. "parent_type" : "order",
  6. "query" : {
  7. "match_all" : {
  8. }
  9. }
  10. }
  11. }
  12. }

聚和查询

  1. GET myorder/_search
  2. {
  3. "query": {
  4. "parent_id": {
  5. "type": "suborder",
  6. "id": "10001"
  7. }
  8. },
  9. "aggs": {
  10. "parents12312": {
  11. "terms": {
  12. "field": "order_join#order"
  13. },
  14. "aggs": {
  15. "sumAmount": {
  16. "stats": {
  17. "field": "amount"
  18. }
  19. }
  20. }
  21. }
  22. }
  23. }

子聚会查询

  1. GET myorder/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "parent": {
  6. "children": {
  7. "type": "suborder"
  8. },
  9. "aggs": {
  10. "sumAmount": {
  11. "stats": {
  12. "field": "amount"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }

聚合加筛选:

  1. GET myorder/_search
  2. {
  3. "query": {
  4. "has_child" : {
  5. "type" : "suborder",
  6. "query" : {
  7. "match_all" : {
  8. }
  9. }
  10. }
  11. },
  12. "aggs": {
  13. "parent": {
  14. "children": {
  15. "type": "suborder"
  16. },
  17. "aggs": {
  18. "fields": {
  19. "terms": {
  20. "field": "orderId"
  21. },
  22. "aggs": {
  23. "sumAmount": {
  24. "sum": {
  25. "field": "amount"
  26. }
  27. },
  28. "having": {
  29. "bucket_selector": {
  30. "buckets_path": {
  31. "orderCount": "_count",
  32. "sumAmount": "sumAmount"
  33. },
  34. "script": {
  35. "source": "params.sumAmount >= 100 && params.orderCount >=0"
  36. }
  37. }
  38. }
  39. }
  40. }
  41. }
  42. }
  43. }
  44. }

定义一对多的索引

一对一的索引模型很难满足日常业务的数据处理,es也支持一对多的join

  1. PUT myorder
  2. {
  3. "mappings": {
  4. "_doc": {
  5. "properties": {
  6. "order_join": {
  7. "type": "join",
  8. "relations": {
  9. "order": ["suborder1", "suborder2"],
  10. "suborder2":"suborder3"
  11. }
  12. }
  13. }
  14. }
  15. }
  16. }

上面的索引的关联的关系如下:

  1. order
  2. / \
  3. suborder1 suborder2
  4. \
  5. suborder3

nested:嵌套

概念解释:
数组键值对查询会出现数据查询误差,Nested解决键值对查询误差
嵌套类型是对象数据类型的一个特例,允许对象数组彼此独立地进行索引和查询, 可以让array类型的对象被独立索引和搜索.
内置实现:
存储多条文档数据,通过内置查询关联合并为一条数据
注意事项:

  1. 嵌套深度
  2. 单条嵌套数据量条数限制
  3. 字段嵌套数量限制默认50
  4. 字段嵌套对象限制默认10000

使用场景:
子文档(例如:上面的user), 较少更新,查询频繁的场景

说明:

当不使用nested字段类型时候,对于某个字段,其值是一个列表
image.png
如上图,用户张三 和 李四的信息混合到一起,此时查找张四,同样可以获取

  1. PUT test-009/_doc/1
  2. {
  3. "group": "fans",
  4. "user": [
  5. {
  6. "first": "张",
  7. "last": "三"
  8. },
  9. {
  10. "first": "李",
  11. "last": "四"
  12. }
  13. ]
  14. }
  15. GET test-009/_search
  16. {
  17. "query": {
  18. "bool": {
  19. "filter": [
  20. {
  21. "term": {
  22. "user.first.keyword": "张"
  23. }
  24. },
  25. {
  26. "term": {
  27. "user.last.keyword": "四"
  28. }
  29. }
  30. ]
  31. }
  32. }
  33. }

设置nested类型

image.png
如上图,设置user字段类型为 nested, 在lucene内部,会存储为3个文档,其中nested类型的每个元素都作为一个独立的文档存在
注意:查询nested字段需要使用nested查询语法

  1. DELETE test-009
  2. PUT test-009/
  3. {
  4. "mappings": {
  5. "properties": {
  6. "user": {
  7. "type": "nested"
  8. }
  9. }
  10. }
  11. }
  12. PUT test-009/_doc/1
  13. {
  14. "group": "fans",
  15. "user": [
  16. {
  17. "first": "张",
  18. "last": "三"
  19. },
  20. {
  21. "first": "李",
  22. "last": "四"
  23. }
  24. ]
  25. }
  26. GET test-009/_search
  27. {
  28. "query": {
  29. "nested": {
  30. "path": "user",
  31. "query": {
  32. "bool": {
  33. "filter": [
  34. {
  35. "term": {
  36. "user.first.keyword": "张"
  37. }
  38. },
  39. {
  40. "term": {
  41. "user.last.keyword": "三"
  42. }
  43. }
  44. ]
  45. }
  46. }
  47. }
  48. }
  49. }

辅助字段类型应用

alias别名:

  • 命名应用:

字段代理
字段指向
避免直接暴露原始字段

  • 注意事项:

数据不可以更新
别名不存储任何数据,仅仅是路径指向

  1. PUT test-008
  2. {
  3. "mappings": {
  4. "properties": {
  5. "company1":{
  6. "type": "text"
  7. },
  8. "companyName":{
  9. "type": "alias",
  10. "path":"company1"
  11. }
  12. }
  13. }
  14. }
  15. POST test-008/_doc
  16. {
  17. "company1":"liwenjun"
  18. }
  19. GET test-008/_search
  20. {
  21. "query": {
  22. "match": {
  23. "companyName": "liwenjun"
  24. }
  25. }
  26. }

单值多字段:

Multi-fileds
概念定义:
一个字段用途多种场景,可以设计为多种类型同时支持原数据仅存储一份,节约空间
应用领域:
多用途多场景检索需求
如:字符检索效率比数值要高效

  1. PUT test-100
  2. {
  3. "mappings": {
  4. "properties": {
  5. "name":{
  6. "type": "text",
  7. "fields": {
  8. "keyword" :{
  9. "type":"keyword"
  10. },
  11. "age":{
  12. "type":"integer"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }
  19. POST test-100/_doc
  20. {
  21. "age": 11
  22. }
  23. GET test-100/_search

Copy_to

概念定义:
字段数据来源去其他字段,在原数据中不存储
应用领域:
多字段同时组合检索,节约组合字段空间资源

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

地理与多边形图形类型应用

geo_point:地理位置

概念介绍:

  1. 基于经纬度坐标,应用与地址位置检索领域
  2. 基于geohash算法

geo_shape:地理图形
概念定义

  1. 基于地理位置坐标点,扩展了地理位置多边形区域搜索类型,基于球体模型设计检索
  2. 默认quadtree四叉树算法,可以选择geohash

支持图形
1.支持多种图形
image.png

特殊行业字段类型应用

ip网络地址

概念定义:
支持IPV4,IPV6,同时支持
image.png

runtime运行时字段类型应用

概念定义:

  1. 查询运行时,字段才会计算实际值;
  2. 比占用source,不占用磁盘
  3. 一般使用脚本方式,需要计算,性能与便利需要平衡
  4. 创建复杂表达式,使用的是painless脚本

使用方式:

  1. 索引创建mapping时定义,查询时使用
  2. 查询时定义,查询时使用

image.png

Mapper字段源码解读