【问题标题】:How to handle nulls in an Elasticsearch index如何处理 Elasticsearch 索引中的空值
【发布时间】:2020-03-06 10:37:38
【问题描述】:

我有一个要导出到 Elasticsearch 的 SQL 表。

其中一列是可为空的数值字段,在某些记录中为空。

当我们尝试索引表时,我们得到这个错误:

One of the ETL (BigQuery -> ElasticSearch) jobs for Table : MLS has been ES Failed Chunk of 10000 from index 20000 possibly due to incompatible objects.

Failing BigQuery Table: MLS

Stack Trace of the error:

Traceback (most recent call last): File "/Users/asif/zodiacbackend/zodiacbackend/tasks.py", line 205, in insertIntoES helpers.bulk(es, doc_generator(dataframe,table)) File "/Users/asif/zodiacbackend/env/lib/python3.7/site-packages/elasticsearch/helpers/actions.py", line 300, in bulk for ok, item in streaming_bulk(client, actions, *args, **kwargs): File "/Users/asif/zodiacbackend/env/lib/python3.7/site-packages/elasticsearch/helpers/actions.py", line 230, in streaming_bulk **kwargs File "/Users/asif/zodiacbackend/env/lib/python3.7/site-packages/elasticsearch/helpers/actions.py", line 158, in _process_bulk_chunk raise BulkIndexError("%i document(s) failed to index." % len(errors), errors) elasticsearch.helpers.errors.BulkIndexError: ('2 document(s) failed to index.', [{'index': {'_index': 'mls', '_type': 'mls', '_id': 'b100qHABEFI45Lp-z3Om', 'status': 400, 'error': {'type': 'illegal_argument_exception', 'reason': 'mapper [Lot_Size_Sq_Ft] of different type, current_type [text], merged_type [long]'}, 'data': { 'Lot_Size_Sq_Ft': Decimal('13504')}}}]) 

如何让系统识别空值?

【问题讨论】:

  • 你有没有机会看看我的答案,如果你需要任何澄清,请随时评论我的答案
  • 我们现在正在处理它。我感谢你的耐心和智慧。我会尽快回复您。
  • 好的,非常感谢更新:)

标签: elasticsearch null elasticsearch-query


【解决方案1】:

用户 WittyID,错过了一些重要的事情,例如:

  1. null_value 的值必须与您的字段具有相同的数据类型,因此在他的示例中,他声明了integer 字段但将NULL 定义为null_values,将抛出json_parse_exception,这是在official link 中称为important 如下:

null_value 需要与字段的数据类型相同。为了 例如,长字段不能有字符串 null_value。

  1. null_value 只影响数据的索引方式,它不会修改 _source 文档,因此在您的源文档中,无论您传递什么,都会被存储,而不是 null_values 参数中提到的那个和在查询时,您还需要使用值 null_value 参数。

简而言之,null 在 ES 中无法识别,因此您可以为 null 定义自定义值,然后使用它来索引和查询 null 值。使用下面的例子,任何人都可以尝试:

创建索引

{
  "mappings": {
    "properties": {
      "my_signed_integer": {
        "type":"integer",
        "null_value": -1 --> note we defining `null` values as `-1`.
      }
    }
  }
}

索引文档

  1. 存储null整数文档

    { “我的号码”:空 }

如果你从 ES 得到这个文档,它会返回如下:

{
   "_index": "so-6053847",
   "_type": "_doc",
   "_id": "1",
   "_version": 1,
   "_seq_no": 0,
   "_primary_term": 1,
   "found": true,
   "_source": {
      "my_number": null. --> As explained earlier, in source its stored as `null`.
   }
}
  1. 索引非负值

    { “我的号码”:10 }

搜索查询以获取具有 null 值的整数

{
  "query": {
    "term": {
      "my_signed_integer": -1 -->notice same `null_value`, you need to mention
    }
  }
}

结果:

 "hits": [
         {
            "_index": "so-6053847",
            "_type": "_doc",
            "_id": "1",
            "_score": 1.0,
            "_source": {
               "my_signed_integer": null --> notice it shows `null`, not `-1`
            }
         }
      ]

搜索查询其他数字(非空),即在我们的例子中为10

{
  "query": {
    "term": {
      "my_signed_integer": 10
    }
  }
}

结果

"hits": [
         {
            "_index": "so-6053847",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.0,
            "_source": {
               "my_signed_integer": 10 -->source matches the indexed value for this doc
            }
         }
      ]

【讨论】:

  • 这就像一个魅力。谢谢你。感谢您的耐心。新安装。
  • @arcee123,很高兴它有帮助,感谢您接受和支持,值得等待和美好的一天开始 :-)
  • 喜欢这个答案!您也是 ElasticSearch 的新手,您掌握了这个主题并如此清楚地解释了它,而且都在同一个地方。接受我投票的善良陌生人
【解决方案2】:

您正在处理一个普通的 ES 头部刮刀。 Elasticsearch doesn't index null values(不仅仅是数字空值)。您需要在索引映射中指定您希望如何为任何检测到的空值建立索引。像这样的:

  "mappings": {
    "properties": {
      "nullable_numeric": {
        "type":       "integer",
        "null_value": -1 
      },
      "nullable_text": {
       "type":        "text",
       "null_value":  "NULL"
    }
  }

一旦你这样做了,ES 就会知道如何正确索引这些字段。请注意,您不需要更改原始数据,只需让 ES 知道如何索引空值以进行搜索....顺便说一下,当您查询 ES 时不会影响文档。

【讨论】:

  • 这只是忽略空值吗?还是忽略整列,因为有些是空值?
  • 它不会忽略空值或整个列,它会将空值索引为您作为“null_value”放置的任何内容。例如,您的 null_value 可以是“嘿,Lucene,每当您看到空值时,将其索引为此处的文本”。如果没有那个 null_value,Elasticsearch 不知道如何索引一个空/null 值。同样,这不会影响您的文档。当您查询同一个文档时,您会看到与 BigQuery 中一样的数字空值……这仅适用于 Elasticsearch 的索引。
  • 好的。所以我们将 null_value 设为任意值,但是当有人进行查询时,它仍然返回为 null?
  • 是的,请记住警告(请参阅 Opster Elasticsearch Ninja 的回答),即任意事物需要与字段映射到的类型相同。
猜你喜欢
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 2016-06-24
  • 1970-01-01
  • 2015-10-27
  • 2017-05-07
  • 1970-01-01
相关资源
最近更新 更多