Mapping映射
1 什么是Mapping
Mapping定义了文档字段的类型和属性,类似于关系型数据库的表结构
# 查看索引的Mapping
GET /my_index/_mapping

# 创建索引时定义Mapping
PUT /my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "standard"
      },
      "publish_date": {
        "type": "date",
        "format": "yyyy-MM-dd"
      },
      "views": {
        "type": "integer"
      }
    }
  }
}
2 常用字段类型
类型 说明 示例
text 全文搜索文本,会被分词 文章内容、描述
keyword 精确值,不分词,用于过滤/排序 标签、状态、邮箱
integer 32位整数 年龄、数量
long 64位整数 大数值
float 32位浮点数 价格、评分
double 64位浮点数 精确小数
date 日期类型 创建时间、更新时间
boolean 布尔类型 true/false
object JSON对象 嵌套对象
nested 嵌套类型,支持独立查询 数组对象
geo_point 地理坐标 经纬度
ip IP地址 IPv4/IPv6
3 text vs keyword
理解两种字符串类型的区别
# 多字段映射(同时支持全文和精确匹配)
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

# 使用方式
# 全文搜索:title
# 精确匹配:title.keyword
# 排序聚合:title.keyword

GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "elasticsearch" } }
      ],
      "filter": [
        { "term": { "title.keyword": "Elasticsearch Guide" } }
      ]
    }
  },
  "sort": [
    { "title.keyword": "asc" }
  ]
}
4 动态Mapping
控制自动检测字段类型的行为
# 禁用动态Mapping
PUT /my_index
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "title": { "type": "text" }
    }
  }
}

# 动态模板
PUT /my_index
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings_as_keywords": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      },
      {
        "longs_as_integers": {
          "match_mapping_type": "long",
          "mapping": {
            "type": "integer"
          }
        }
      }
    ]
  }
}
5 完整Mapping示例
PUT /blog
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "author": {
        "type": "keyword"
      },
      "tags": {
        "type": "keyword"
      },
      "category": {
        "type": "keyword"
      },
      "publish_date": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      },
      "views": {
        "type": "integer"
      },
      "rating": {
        "type": "float"
      },
      "is_published": {
        "type": "boolean"
      },
      "location": {
        "type": "geo_point"
      },
      "comments": {
        "type": "nested",
        "properties": {
          "user": { "type": "keyword" },
          "content": { "type": "text" },
          "date": { "type": "date" }
        }
      }
    }
  }
}