MST

星途 面试题库

面试题:ElasticSearch索引结构优化之文档模型设计

假设你正在设计一个包含多种复杂关系数据的ElasticSearch索引,在文档模型设计方面,如何利用ElasticSearch的索引结构特点,以实现高效的查询和存储,同时减少冗余数据?请举例说明。
25.1万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试

1. 利用嵌套对象(Nested Objects)处理一对多关系

  • 结构特点:Elasticsearch 中的嵌套对象允许在单个文档内存储相关的对象数组,每个嵌套对象都可以独立地被索引和查询。这避免了将相关对象拆分到多个文档导致的数据冗余,同时能高效查询。
  • 举例:假设我们有一个博客文章索引,一篇文章可能有多个评论。我们可以这样设计文档结构:
{
  "title": "My Blog Post",
  "content": "This is the content of my blog post.",
  "comments": [
    {
      "author": "John",
      "text": "Great post!"
    },
    {
      "author": "Jane",
      "text": "I learned a lot."
    }
  ]
}
  • 查询示例:要查询包含特定评论作者的文章,可以使用以下查询:
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "match": {
          "comments.author": "John"
        }
      }
    }
  }
}

2. 使用父子文档(Parent - Child Relationships)处理更复杂层次关系

  • 结构特点:父子文档允许将相关文档分组,父文档和子文档有明确的关联关系。这种结构适用于需要保持文档之间层次关系且不希望过多冗余数据的场景。
  • 举例:以电商产品为例,一个产品可以有多个变体(如不同颜色、尺寸)。产品作为父文档,变体作为子文档。
    • 父文档(产品)
{
  "product_id": "12345",
  "name": "T - Shirt",
  "description": "A comfortable T - Shirt"
}
- **子文档(变体)**:
{
  "product_id": "12345",
  "variant_id": "1",
  "color": "Red",
  "size": "M"
}
  • 查询示例:查询某个产品的所有变体,可以使用has_child查询:
{
  "query": {
    "has_child": {
      "type": "variant",
      "query": {
        "match_all": {}
      }
    }
  }
}

3. 避免过度嵌套,保持适度冗余

  • 结构特点:虽然嵌套对象和父子文档能减少冗余,但过度嵌套会导致查询性能下降。在某些情况下,为了查询性能,可以接受一定程度的冗余。
  • 举例:在一个包含员工及其所属部门信息的索引中,如果经常需要按部门查询员工,并且部门信息变动不频繁,可以在员工文档中重复部门的关键信息(如部门名称、部门ID),而不是通过复杂的嵌套或父子关系查询。
{
  "employee_name": "Alice",
  "department_id": "101",
  "department_name": "Engineering",
  "job_title": "Software Engineer"
}

这样在查询特定部门的员工时,无需复杂的跨文档或嵌套查询,能直接在员工文档中匹配部门信息,提高查询效率。