【问题标题】:Elastic search parse as object but found nested values弹性搜索解析为对象但发现嵌套值
【发布时间】:2020-06-29 03:31:10
【问题描述】:

我目前正在从事一个项目,我将以前处理的数据存储在 csv 中,我想尝试使用 ElasticSearch + Kibana 来分析我的数据*。问题是我有一个包含 json 值的列和一些以嵌套类型发送的 None 值。为了清理无,我将其替换为“null”,但出现以下错误:

Tried to parse field as object but found a concrete value

我认为 ES 不喜欢可能具有“NULL”或嵌套类型的字段。我该如何解决这个问题并保持空值的原则以允许以后过滤?感谢您的帮助:)

我正在使用 python 和 eland module 处理将 pandas 数据帧发送到 ES。

ES version:
'version': {'number': '7.7.0',
  'build_flavor': 'default',
  'build_type': 'deb',
  'build_hash': '81a1e9eda8e6183f5237786246f6dced26a10eaf',
  'build_date': '2020-05-12T02:01:37.602180Z',
  'build_snapshot': False,
  'lucene_version': '8.5.1',
  'minimum_wire_compatibility_version': '6.8.0',
  'minimum_index_compatibility_version': '6.0.0-beta1'},
 'tagline': 'You Know, for Search'}

编辑

我正在使用下面的代码提取 (python3) 发送我的数据,感谢 @Gibbs 的回答,现在可以正常工作


INDEX_NAME = 'my_index'
DATA_PATH = './data4analysis.csv'
def csv_jsonconverter_todict(field):
    if not field:
        return {'null_value': 'NULL'}
    if "'" in field:  # cleaning if bad json column, ok for me
        field = field.replace("'", '"')
    try:
        return json.loads(field)
    except Exception as e:
        logger.exception('json.loads(field) failed on field= %s', field, exc_info=True)
        raise e


def loadNprepare_data(path, sep=';'):
    df = pd.read_csv(path, sep=sep, encoding='cp1252',
                     converters={'ffprobe': csv_jsonconverter_todict)

    # cleaning NaNs to avoid " json_parse_exception Non-standard token 'NaN'"
    df = df.applymap(lambda cell: 'null_value' if pd.isna(cell) or not cell else cell)
    return df

if __name__ == '__main__':
    es_client = Elasticsearch(hosts=[ES_HOST], http_compress=True)

    if es_client.indices.exists(INDEX_NAME):
        logger.info(f"deleting '{INDEX_NAME}' index...")
        res = es_client.indices.delete(index=INDEX_NAME)
        logger.info(f"response: '{res}'")

    # since we are running locally, use one shard and no replicas
    request_body = {
        "settings": {
            "number_of_shards": 1,
            "number_of_replicas": 0
        }
    }
    logger.info(f"creating '{INDEX_NAME}' index...")
    res = es_client.indices.create(index=INDEX_NAME, body=request_body)
    logger.info(f" response: '{res}'")

    logger.info("Sending data to ES")

    data = loadNprepare_data(DATA_PATH)
    try:
        el_df = eland.pandas_to_eland(data, es_client,
                                      es_dest_index=INDEX_NAME,
                                      es_if_exists='replace',
                                      es_type_overrides= {'ffprobe': 'nested'})
    except Exception as e:
        logger.error('Elsatic Search error', exc_info=True)
        raise e

【问题讨论】:

    标签: python-3.x dataframe elasticsearch


    【解决方案1】:

    问题是您为列定义了type。而您正试图在该列中插入字符串'null'

    不支持两种不同的类型。如果您按照here 所述进行操作,它将接受 Null 值

    无法索引或搜索空值。当一个字段设置为 null(或一个空数组或一个空值数组)时,它被视为该字段没有值。

    null_value 参数允许您将显式的空值替换为指定的值,以便对其进行索引和搜索

    【讨论】:

      【解决方案2】:

      您是否尝试将 DataFrame 导入 Elasticsearch 到现有索引中?否则,查看 Eland 为您创建的映射并查看哪个字段映射到您不期望的类型可能是值得的。如果您计划在 Elasticsearch 中使用空值,您可能需要将某些数字字段设为“可空”。

      from elasticsearch import Elasticsearch
      es = Elasticsearch(<your cluster info>)
      resp = es.indices.get_mapping("<your index>")
      print(resp)
      

      如果您能够发布您的索引映射和您插入的 CSV 行类型的示例,那么我也可以为您提供帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多