如何获取elasticsearch索引中的所有字段名称

时间:2017-03-17 17:15:47

标签: elasticsearch

我刚开始使用elasticsearch 5.2。

我正在尝试获取索引中的所有键  如果我有以下映射:

"properties": {
         "name": { "type": "text" },
         "article": {
          "properties": {
           "id": { "type": "text" },
           "title":  { "type": "text"},
           "abstract": { "type": "text"},
            "author": {
             "properties": {
              "id": { "type": "text" },
              "name": { "type": "text" }
}}}} } }

是否可以获取所有字段的全名?  像这样:

 name,
 article.id ,
 article.title ,
 article.abstract ,
 article.author.id,
 article.author.name

我怎么能得到它?

3 个答案:

答案 0 :(得分:1)

映射API还允许直接查询字段名称。 这是一个python 3代码片段,应该做的工作:

import json
import requests

# get mapping fields for a specific index:
index = "INDEX_NAME"
elastic_url = "http://ES_HOSTNAME:9200"
doc_type = "DOC_TYPE"
mapping_fields_request = "_mapping/field/*?ignore_unavailable=false&allow_no_indices=false&include_defaults=true"
mapping_fields_url = "/".join([elastic_url, index, doc_type, mapping_fields_request])
response = requests.get(mapping_fields_url)

# parse the data:
data = response.content.decode()
parsed_data = json.loads(data)
keys = sorted(parsed_data[index]["mappings"][doc_type].keys())
print("index= {} has a total of {} keys".format(index, len(keys)))

# print the keys of the fields:
for i, key in enumerate(keys):
    if i % 43 == 0:
        input()
    print("{:4d}:     {}".format(i, key))

确实很方便。 请注意包含"。"的键。在他们的名字中可能会让你有点混淆他们在文件中的级联......

答案 1 :(得分:0)

您可以使用_field_names字段。

  

_field_names字段索引文档中每个字段的名称   包含除null之外的任何值。

GET _search
{
  "size"0,
  "aggs": {
    "Field names": {
      "terms": {
        "field": "_field_names", 
        "size": 100
      }
    }
  }
}

更新:从ES 5开始

  

_field_names字段已被锁定,仅被编入索引   不支持fielddata(内存密集型)或doc值,

参考:https://github.com/elastic/elasticsearch/issues/22576

作为替代方案,您可以getMapping API

  

get mapping API可用于获取多个索引或类型   使用单个调用进行映射。 API的一般用法如下   语法如下:host:port / {index} / _ mapping / {type}

$ curl -XGET 'http://localhost:9200/index/_mapping?pretty'

然后,您可以处理响应以提取索引中的所有字段名称

答案 2 :(得分:0)

您可以试试这个,Get Field Mapping API

def unique_preserving_order(sequence):
    """
    Preserving Order
    :param sequence: object list
    :return:  new list from the set’s contents
    """

    seen = set()
    return [x for x in sequence if not (x in seen or seen.add(x))]

以递归方式获取es索引字段

def get_fields_recursively(dct, field_types=None):

    if dct and 'properties' in dct:
        fields = []
        for key, ndct in dct.get('properties').items():
            if 'properties' in ndct:
                for nkey, nd in ndct.items():
                    if nkey == 'properties':
                        field = get_fields_recursively(ndct)

                        if field_types:
                            for f in field:
                                prop = ndct.get('properties').get(f)
                                if prop and prop.get('type') in field_types:
                                    ff = '{0}.{1}'.format(key, f)
                                    # fields.append(f)
                                    fields.append(ff)
                        else:
                            # if not key.startswith('@'):
                            # _fields = field + ['{0}.{1}'.format(key, f) for f in field]
                            _fields = ['{0}.{1}'.format(key, f) for f in field]
                            fields.extend(_fields)
                        continue

                continue

            if field_types:
                if ndct.get('type') in field_types and not key.startswith('@'):
                    fields.append(key)
            else:
                if not key.startswith('@'):
                    fields.append(key)
        return fields
    else:
        return dct

从索引映射中获取字段,您也可以按类型过滤字段,例如。文本字段或数字字段

def get_mapping_fields(self, field_type=None, index=None, params={}):
    """

    :param field_type: es field types, filter fields by type
    :param index: elastic index name
    :param params: mapping additional params
    :return: fields

    <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-field-mapping.html>
    - http://eshost:9200/_mapping
    - http://eshost:9200/_all/_mapping
    - http://eshost:9200/index_name/_mapping

    """

    _fields = []
    _mapping = self.esclient.indices.get_mapping(index=index, params=params)
    for idx_mapping in _mapping.values():
        mapping = idx_mapping.get('mappings')
        if 'system' in mapping:
            mapping = mapping.get('system')
        else:
            mapping = mapping.get('doc')
        fields = get_fields_recursively(mapping, field_type)
        if fields:
            _fields.extend(fields)

    return list(unique_preserving_order(_fields))