美文网首页
ElasticSearch | 对象 | Nested 对象

ElasticSearch | 对象 | Nested 对象

作者: 乌鲁木齐001号程序员 | 来源:发表于2020-05-28 17:51 被阅读0次

在 ElasticSearch 中处理关联关系

  • 在关系型数据库中,一般会考虑范式化数据;而在 ElasticSearch 中,往往考虑反范式化数据;
  • 反范式化的好处:
    • 读数据的速度快;
    • 无需表连接;
    • 无需行锁;
  • ElasticSearch 并不擅长处理关联关系,一般采用以下四种方法处理关联关系:
    • 对象类型
    • 嵌套对象
    • 父子关联关系
    • 应用端关联

案例 | 搜索包含对象数组的文档

数据准备
DELETE my_movies

PUT my_movies
{
      "mappings" : {
      "properties" : {
        "actors" : {
          "properties" : {
            "first_name" : {
              "type" : "keyword"
            },
            "last_name" : {
              "type" : "keyword"
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
}

POST my_movies/_doc/1
{
  "title":"Speed",
  "actors":[
    {
      "first_name":"Keanu",
      "last_name":"Reeves"
    },

    {
      "first_name":"Dennis",
      "last_name":"Hopper"
    }
  ]
}
搜索数据
  • 用第一个演员的名 + 第二个演员的姓居然搜出了结果;
  • 原因:JSON 格式被处理成扁平式键值对的形式:"actors.first_name":["Keanu","Dennis"] "actors.last_name":["Reeves","Hopper"]
  • 可以用 Nested Data Type 解决这个问题;
POST my_movies/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"actors.first_name": "Keanu"}},
        {"match": {"actors.last_name": "Hopper"}}
      ]
    }
  }
}

Nested Data Type

  • 允许对象数组中的对象被独立索引;
  • 使用 nested 和 properties 关键字,将所有 actors 索引到多个分隔的文档;
  • 在内部,Nested 文档会被保存在两个 Lucene 文档中,在查询时做 Join 处理;

Nested Data Type | 搜索包含对象数组的文档

数据准备
DELETE my_movies

PUT my_movies
{
      "mappings" : {
      "properties" : {
        "actors" : {
          "type": "nested",
          "properties" : {
            "first_name" : {"type" : "keyword"},
            "last_name" : {"type" : "keyword"}
          }},
        "title" : {
          "type" : "text",
          "fields" : {"keyword":{"type":"keyword","ignore_above":256}}
        }
      }
    }
}

POST my_movies/_doc/1
{
  "title":"Speed",
  "actors":[
    {
      "first_name":"Keanu",
      "last_name":"Reeves"
    },
    {
      "first_name":"Dennis",
      "last_name":"Hopper"
    }
  ]
}
Nested 查询
  • 在 Nested 查询中,错误的结果就不会命中了;
POST my_movies/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "Speed"
          }
        },
        {
          "nested": {
            "path": "actors",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "actors.first_name": "Keanu"
                    }
                  },
                  {
                    "match": {
                      "actors.last_name": "Hopper"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
对 Nested 对象做聚合分析
POST my_movies/_search
{
  "size": 0,
  "aggs": {
    "actors": {
      "nested": {
        "path": "actors"
      },
      "aggs": {
        "actor_name": {
          "terms": {
            "field": "actors.first_name",
            "size": 10
          }
        }
      }
    }
  }
}
对 Nested 对象做普通聚合是无效的
POST my_movies/_search
{
  "size": 0,
  "aggs": {
    "NAME": {
      "terms": {
        "field": "actors.first_name",
        "size": 10
      }
    }
  }
}

相关文章

网友评论

      本文标题:ElasticSearch | 对象 | Nested 对象

      本文链接:https://www.haomeiwen.com/subject/edhaahtx.html