动态映射适用于开发环境,但对于生产级集群禁用它。 将动态配置为 “strict” 以对索引的字段值实施严格模式。有关动态映射的详细描述,请阅读文章 “Elasticsearch:Dynamic mapping”。
PUT /twitter
{
"mappings": {
"dynamic": "strict",
"properties": {
"subscriptionName": {
"type": "text"
}
}
}
}
当文档大量存储时,可以在定义字段映射时使用优化来节省磁盘空间。
禁用强制(coerce)。强制给你自由,但缺乏纪律。 导致混乱。有关 coerce 的更多描述,请参阅文章 “Elasticsearch:Elasticsearch 中的数据强制匹配”。
PUT /product/_doc/1
{
"price": 890.90
}
PUT /product/_doc/2
{
"price": "890.90"
}
我们可以看出来,第一个是成功的。针对第二个命令,虽然指定为字符串,但 ES 只看到引号 “” 内的浮点数,将数据结构存储为浮点数。它将是成功的。
我们接下来使用如下的命令来写入另外一个文档:
PUT /product/_doc/3
{
"price": "890.90m"
}
上面的命令返回:
{
"error": {
"root_cause": [
{
"type": "document_parsing_exception",
"reason": "[2:12] failed to parse field [price] of type [float] in document with id '3'. Preview of field's value: '890.90m'"
}
],
"type": "document_parsing_exception",
"reason": "[2:12] failed to parse field [price] of type [float] in document with id '3'. Preview of field's value: '890.90m'",
"caused_by": {
"type": "number_format_exception",
"reason": "For input string: \"890.90m\""
}
},
"status": 400
}
这会失败,因为它在内部以浮点形式存储在数据结构中。
我们使用如下的命令来获得文档 2:
GET /product/_doc/2
上面的命令返回:
{
"_index": "product",
"_id": "2",
"_version": 1,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": {
"price": "890.90"
}
}
从上面的输出中,我们可以看到 price 的值还是以字符串的形式来存储的。
我们可以做如下的查询:
GET product/_search?filter_path=**.hits
{
"query": {
"range": {
"price": {
"gte": 890.90
}
}
}
}
上面的命令返回的结果为:r
{
"hits": {
"hits": [
{
"_index": "product",
"_id": "1",
"_score": 1,
"_source": {
"price": 890.9
}
},
{
"_index": "product",
"_id": "2",
"_score": 1,
"_source": {
"price": "890.90"
}
}
]
}
}
从上面的输出中,我们可以看到尽管文档 2 的 price 为 “890.90” 字符串类型,但是查询的结果还是包含它。我们如果做如下的查询:
GET product/_search
{
"query": {
"match": {
"prce": "890.90"
}
}
}
上述查询不会有任何的结果,这个是因为 price 为 float 类型。
请注意数字数据类型,如果足够的话请使用 float,因为 double 需要更多空间。 如果足够的话就使用 Integer,因为 Long 占用更多空间。
对于字符串字段,不需要同时使用文本和关键字映射。 使用多重映射需要空间。 仅当需要聚合、排序、精确匹配过滤时才使用关键字,以确保不进行分词。 使用文本进行全文搜索。 仅在需要时同时使用两者。
多字段(multi-feild)映射 - 将 keyword 映射添加到文本字段
PUT /subscriptions
{
"mappings": {
"properties": {
"description": {
"type": "text"
},
"subscriptionsName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
写入一个文档:
POST /subscriptions/_doc
{
"description": "Detailed subs...",
"subscriptionsName": ["Monthly", "Weekly", "Quarterly"]
}
查询文档:
GET /subscriptions/_search
{
"query": {
"match_all": {}
}
}
查询文本:
GET /subscriptions/_search
{
"query": {
"match": {
"subscriptionsName": "Monthly"
}
}
}
对 keyword 字段进行查询:
GET /subscriptions/_search
{
"query": {
"term": {
"subscriptionsName.keyword": "Monthly"
}
}
}
有关 keyword 及 text 查询的比较,请详细阅读文章 “Elasticsearch:Text vs. Keyword - 它们之间的差异以及它们的行为方式”。
当不需要排序、聚合、过滤时,请将 doc_value 设置为 false。
当不需要相关性评分时,设置 norms 为 false
当不需要对值进行过滤时,请将 index 设置为 false(仍然可以进行聚合,例如时间序列数据)。