Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Картирование ›Параметры картирования

Поля

Часто бывает полезно индексировать одно и то же поле разными способами для разных целей. Это предназначение многопольных полей. Например, поле string может быть прокартировано как поле text для полнотекстового поиска и как поле keyword для сортировки или агрегаций:

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "city": {
                "type": "text",
                "fields": {
                    "raw": {
                        "type": "keyword"
                    }
                }
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="1",
    document={
        "city": "New York"
    },
)
print(resp1)

resp2 = client.index(
    index="my-index-000001",
    id="2",
    document={
        "city": "York"
    },
)
print(resp2)

resp3 = client.search(
    index="my-index-000001",
    query={
        "match": {
            "city": "york"
        }
    },
    sort={
        "city.raw": "asc"
    },
    aggs={
        "Cities": {
            "terms": {
                "field": "city.raw"
            }
        }
    },
)
print(resp3)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        city: {
          type: 'text',
          fields: {
            raw: {
              type: 'keyword'
            }
          }
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 1,
  body: {
    city: 'New York'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 2,
  body: {
    city: 'York'
  }
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match: {
        city: 'york'
      }
    },
    sort: {
      'city.raw' => 'asc'
    },
    aggregations: {
      "Cities": {
        terms: {
          field: 'city.raw'
        }
      }
    }
  }
)
puts response
{
	res, err := es.Indices.Create(
		"my-index-000001",
		es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "city": {
	        "type": "text",
	        "fields": {
	          "raw": {
	            "type": "keyword"
	          }
	        }
	      }
	    }
	  }
	}`)),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "city": "New York"
	}`),
		es.Index.WithDocumentID("1"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "city": "York"
	}`),
		es.Index.WithDocumentID("2"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Search(
		es.Search.WithIndex("my-index-000001"),
		es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "match": {
	      "city": "york"
	    }
	  },
	  "sort": {
	    "city.raw": "asc"
	  },
	  "aggs": {
	    "Cities": {
	      "terms": {
	        "field": "city.raw"
	      }
	    }
	  }
	}`)),
		es.Search.WithPretty(),
	)
	fmt.Println(res, err)
}
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      city: {
        type: "text",
        fields: {
          raw: {
            type: "keyword",
          },
        },
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 1,
  document: {
    city: "New York",
  },
});
console.log(response1);

const response2 = await client.index({
  index: "my-index-000001",
  id: 2,
  document: {
    city: "York",
  },
});
console.log(response2);

const response3 = await client.search({
  index: "my-index-000001",
  query: {
    match: {
      city: "york",
    },
  },
  sort: {
    "city.raw": "asc",
  },
  aggs: {
    Cities: {
      terms: {
        field: "city.raw",
      },
    },
  },
});
console.log(response3);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "city": {
        "type": "text",
        "fields": {
          "raw": { 
            "type":  "keyword"
          }
        }
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "city": "New York"
}

PUT my-index-000001/_doc/2
{
  "city": "York"
}

GET my-index-000001/_search
{
  "query": {
    "match": {
      "city": "york" 
    }
  },
  "sort": {
    "city.raw": "asc" 
  },
  "aggs": {
    "Cities": {
      "terms": {
        "field": "city.raw" 
      }
    }
  }
}

Поле city.raw — это поле keyword версии поля city.

Поле city можно использовать для полнотекстового поиска.

Поле city.raw можно использовать для сортировки и агрегаций

Вы можете добавить многопольные поля к существующему полю, используя API обновления карты.

Если индекс (или поток данных) содержит документы, когда вы добавляете многопольное поле, эти документы не будут содержать значения для нового многопольного поля. Вы можете заполнить новое многопольное поле с помощью API обновления по запросу.

Картирование многопольного поля полностью отделено от карты родительского поля. Многопольное поле не наследует никаких параметров карты от родительского поля. Многопольные поля не изменяют исходное поле _source.

Многопольные поля с несколькими анализаторами

Еще один случай использования многопольных полей — анализ одного и того же поля различными способами для лучшей релевантности. Например, мы можем проиндексировать поле с помощью анализатора standard, который разбивает текст на слова, и снова с помощью анализатора english, который сводит слова к их основе:

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "text": {
                "type": "text",
                "fields": {
                    "english": {
                        "type": "text",
                        "analyzer": "english"
                    }
                }
            }
        }
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="1",
    document={
        "text": "quick brown fox"
    },
)
print(resp1)

resp2 = client.index(
    index="my-index-000001",
    id="2",
    document={
        "text": "quick brown foxes"
    },
)
print(resp2)

resp3 = client.search(
    index="my-index-000001",
    query={
        "multi_match": {
            "query": "quick brown foxes",
            "fields": [
                "text",
                "text.english"
            ],
            "type": "most_fields"
        }
    },
)
print(resp3)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        text: {
          type: 'text',
          fields: {
            english: {
              type: 'text',
              analyzer: 'english'
            }
          }
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 1,
  body: {
    text: 'quick brown fox'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 2,
  body: {
    text: 'quick brown foxes'
  }
)
puts response

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      multi_match: {
        query: 'quick brown foxes',
        fields: [
          'text',
          'text.english'
        ],
        type: 'most_fields'
      }
    }
  }
)
puts response
{
	res, err := es.Indices.Create(
		"my-index-000001",
		es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "text": {
	        "type": "text",
	        "fields": {
	          "english": {
	            "type": "text",
	            "analyzer": "english"
	          }
	        }
	      }
	    }
	  }
	}`)),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "text": "quick brown fox"
	} `),
		es.Index.WithDocumentID("1"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Index(
		"my-index-000001",
		strings.NewReader(`{
	  "text": "quick brown foxes"
	} `),
		es.Index.WithDocumentID("2"),
		es.Index.WithPretty(),
	)
	fmt.Println(res, err)
}

{
	res, err := es.Search(
		es.Search.WithIndex("my-index-000001"),
		es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "multi_match": {
	      "query": "quick brown foxes",
	      "fields": [
	        "text",
	        "text.english"
	      ],
	      "type": "most_fields"
	    }
	  }
	}`)),
		es.Search.WithPretty(),
	)
	fmt.Println(res, err)
}
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      text: {
        type: "text",
        fields: {
          english: {
            type: "text",
            analyzer: "english",
          },
        },
      },
    },
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 1,
  document: {
    text: "quick brown fox",
  },
});
console.log(response1);

const response2 = await client.index({
  index: "my-index-000001",
  id: 2,
  document: {
    text: "quick brown foxes",
  },
});
console.log(response2);

const response3 = await client.search({
  index: "my-index-000001",
  query: {
    multi_match: {
      query: "quick brown foxes",
      fields: ["text", "text.english"],
      type: "most_fields",
    },
  },
});
console.log(response3);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "text": { 
        "type": "text",
        "fields": {
          "english": { 
            "type":     "text",
            "analyzer": "english"
          }
        }
      }
    }
  }
}

PUT my-index-000001/_doc/1
{ "text": "quick brown fox" } 

PUT my-index-000001/_doc/2
{ "text": "quick brown foxes" } 

GET my-index-000001/_search
{
  "query": {
    "multi_match": {
      "query": "quick brown foxes",
      "fields": [ 
        "text",
        "text.english"
      ],
      "type": "most_fields" 
    }
  }
}

Поле text использует анализатор standard.

Поле text.english использует анализатор english.

Индексируем два документа: один с fox, а другой с foxes.

Запрашиваем и объединяем оценки для полей text и text.english.

Поле text содержит термин fox в первом документе и foxes во втором. Поле text.english содержит fox для обоих документов, поскольку foxes сводится к fox.

Строка запроса также анализируется анализатором standard для поля text и анализатором english для поля text.english. Сводное поле позволяет запросу по foxes также соответствовать документу, содержащему только fox. Это позволяет нам сопоставить как можно больше документов. Запросив также необработанное поле text, мы повышаем релевантность оценки документа, который точно соответствует foxes.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/multi-fields.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API