Fields(多字段)

fields 映射参数允许您通过定义额外的子字段,以多种方式索引同一个字段。使用多字段时,主字段值会使用其主要映射进行存储。此外,您可以配置一个或多个具有替代映射的子字段,例如不同的数据类型或分析器,以支持不同的搜索和聚合需求。

当您需要对数据的一种表示形式执行全文搜索,而对另一种表示形式执行精确匹配操作(如排序或聚合)时,多字段特别有用。此外,您可以使用不同的分析器索引同一字段。例如,一个子字段可能使用默认分析器进行通用文本搜索,而另一个子字段使用自定义分析器生成 n-gram 以支持自动补全或模糊匹配。

配置多字段

在以下示例中,创建了一个名为 articles 的索引,其中包含一个被分析为全文的 title 字段。在 fields 下定义了一个名为 raw 的子字段,用于将相同的值存储为 keyword 类型,以便进行精确匹配查询:

PUT /articles
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "raw": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

使用不同的分析器

在以下示例中,同一 title 字段使用两种不同的分析器进行索引。主字段使用默认分析器进行全文搜索,而 ngrams 子字段使用自定义的 n-gram 分析器以支持自动补全等功能:

PUT /articles
{
  "settings": {
    "analysis": {
      "analyzer": {
        "ngram_analyzer": {
          "tokenizer": "ngram_tokenizer",
          "filter": [
            "lowercase"
          ]
        }
      },
      "tokenizer": {
        "ngram_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 4,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "raw": {
            "type": "keyword"
          },
          "ngrams": {
            "type": "text",
            "analyzer": "ngram_analyzer"
          }
        }
      }
    }
  }
}

索引文档

创建索引后,您可以将文档索引到其中。title 字段将按照其映射定义进行处理,其子字段将提供同一值的替代表示形式:

PUT /articles/_doc/1
{
  "title": "Understanding Multi-Fields in Search"
}

查询多字段

您可以在查询中定位额外的子字段以满足不同的需求。例如,要对标题的精确值执行聚合,请使用以下请求查询 title.raw 子字段:

POST /articles/_search
{
  "size": 0,
  "aggs": {
    "titles": {
      "terms": {
        "field": "title.raw"
      }
    }
  }
}

title.raw 子字段映射为 keyword 类型,即使原始标题字段是全文分析的,也允许进行精确匹配聚合:

{
  ...
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "titles": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "Understanding Multi-Fields in Search",
          "doc_count": 1
        }
      ]
    }
  }
}

或者,要使用自动补全功能,您可以在 title.ngrams 子字段上运行 match 查询:

POST /articles/_search
{
  "query": {
    "match": {
      "title.ngrams": "Und"
    }
  }
}

title.ngrams 子字段使用自定义的 n-gram 分析器,因此前缀 “Und” 成功匹配单词 “Understanding” 的开头:

{
  ...
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "articles",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "title": "Understanding Multi-Fields in Search"
        }
      }
    ]
  }
}