Elasticsearch 索引如何建立:索引结构设计, 需要分词的字段,需要索引但不分词的字段,仅存储但不索引的字段,经纬度字段的索引规则,复合字段的存储策略,copy_to聚合字段

Elasticsearch 索引如何建立:索引结构设计, 需要分词的字段,需要索引但不分词的字段,仅存储但不索引的字段,经纬度字段的索引规则,复合字段的存储策略,copy_to聚合字段

Elasticsearch 索引建立指南

1. 索引结构设计

在建立 Elasticsearch 索引时,需要根据字段的用途选择合适的 mapping 方式。主要从以下几个维度进行分析:

  • 是否需要分词:针对全文搜索的数据,通常需要分词(如文章内容、商品描述等)。
  • 是否用于搜索:决定字段是否需要被检索(如用户 ID 可能不用于搜索)。
  • 是否需要存储:部分字段仅用于索引,不需要存储(如日志数据的原始文本可能不存储)。
  • 是否需要聚合:如品牌、类别等字段可能用于聚合统计。
  • 是否唯一:如用户 ID、邮箱等唯一值可以不分词,且通常不需要索引。

2. 不同类型字段的索引策略

2.1 需要分词的字段

  • 文章内容 (content)
  • 商品描述 (description)
  • 网络热词 (hot_keywords)
示例索引:
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "content": {
    
    
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "description": {
    
    
        "type": "text",
        "analyzer": "ik_smart"
      },
      "hot_keywords": {
    
    
        "type": "text",
        "analyzer": "standard"
      }
    }
  }
}

2.2 需要索引但不分词的字段

  • 品牌 (brand)
  • 类别 (category)
  • 人名 (person_name)
  • 地名 (location)
  • 标签 (tags)
示例索引:
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "brand": {
    
    
        "type": "keyword"
      },
      "category": {
    
    
        "type": "keyword"
      },
      "person_name": {
    
    
        "type": "keyword"
      },
      "location": {
    
    
        "type": "keyword"
      },
      "tags": {
    
    
        "type": "keyword"
      }
    }
  }
}

2.3 仅存储但不索引的字段

  • 邮箱 (email)
  • 电话号码 (phone)
  • 用户 ID (user_id)
  • 隐私数据 (private_data)
示例索引:
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "email": {
    
    
        "type": "keyword",
        "index": false
      },
      "phone": {
    
    
        "type": "keyword",
        "index": false
      },
      "user_id": {
    
    
        "type": "keyword",
        "index": false
      },
      "private_data": {
    
    
        "type": "keyword",
        "index": false
      }
    }
  }
}

2.4 经纬度字段的索引规则

可以参照 Elastic 中国社区官方博客Elasticsearch:Geo Point 和 Geo Shape 查询解释,里面有如何传参的详细说明

  • 地理坐标 (location) - 适用于 geo_point 类型,存储单个经纬度点。
    在这里插入图片描述

  • 地理区域 (geo_area) - 适用于 geo_shape 类型,存储多边形、线、圆等地理形状。
    在这里插入图片描述

示例索引:
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "location": {
    
    
        "type": "geo_point"
      },
      "geo_area": {
    
    
        "type": "geo_shape"
      }
    }
  }
}
说明:
  • geo_point:用于存储单个经纬度坐标点,常用于位置搜索和排序。

    • 示例数据:
      {
              
              
        "location": {
              
              
          "lat": 40.7128,
          "lon": -74.0060
        }
      }
      
    • 适用场景:
      • 附近地点搜索(geo_distance 查询)。
      • 位置排序(按距离升序或降序)。
      • 位置过滤(geo_bounding_box)。
  • geo_shape:用于存储复杂的地理形状,如多边形、线、圆等,适用于地理区域查询。

    • 示例数据:
      {
              
              
        "geo_area": {
              
              
          "type": "polygon",
          "coordinates": [[[30, 10], [40, 40], [20, 40], [10, 20], [30, 10]]]
        }
      }
      
    • 适用场景:
      • 地理围栏(geo_shape 查询)。
      • 区域匹配(如某个点是否在指定区域内)。
      • 复杂路径匹配(如物流线路)。

3. 复合字段的存储策略

有时候,我们希望同时支持全文检索精确匹配,可以使用 textkeyword 的组合类型。

示例索引:
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "title": {
    
    
        "type": "text",
        "analyzer": "ik_max_word",
        "fields": {
    
    
          "raw": {
    
    
            "type": "keyword"
          }
        }
      }
    }
  }
}

4. 额外优化建议

  • 使用 copy_to 聚合多个字段,方便搜索时匹配多个字段内容
  • 为大文本字段启用 ignore_above 限制索引的最大长度,避免存储过长数据
  • 合理选择 analyzerik_max_word 适合搜索,ik_smart 适合精准匹配)
  • 避免对高基数字段(如 emailuser_id)建立索引,以减少存储开销

5. 结论

根据数据的不同用途,我们需要合理选择索引策略:

  • 全文搜索字段 使用 text 并配置合适的 analyzer
  • 精确匹配字段 使用 keyword,避免分词。
  • 非检索字段 直接 index: false,减少索引存储。
  • 复合查询字段 结合 textkeyword 进行优化。
  • 地理位置字段 使用 geo_pointgeo_shape 进行索引。

这样可以在保证搜索效率的同时,减少不必要的索引开销,提高 Elasticsearch 的查询性能和存储效率。