如何处理 Elasticsearch 索引中的空值
How to handle nulls in an Elasticsearch index
我有一个 SQL table 正在导出到 Elasticsearch。
其中一列是可以为 null 的数字字段,在某些记录中有 null。
当我们尝试索引 table 时,我们得到这个错误:
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')}}}])
如何让系统识别空值?
您正在处理一个常见的 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 时不会影响文档。
用户 WittyID,错过了一些重要的事情,例如:
null_value
的值必须与您的字段具有相同的数据类型,因此在他的示例中,他声明了 integer
字段但将 NULL
定义为 null_values
, 会抛出 json_parse_exception
并且这在 official link 中被称为 important
如下:
The null_value needs to be the same data type as the field. For
instance, a long field cannot have a string null_value.
null_value
仅影响数据的索引方式,它不会修改 _source 文档,因此在您的源文档中,无论您传递什么,都将被存储,而不是提到的那个在 null_values
参数和查询时,您还需要使用值 null_value
参数。.
简而言之,ES 无法识别 null
,因此您可以为 null
定义自定义值,然后使用它来索引和查询 null
values.It 使用下面的示例很容易解释整个事情,任何人都可以尝试:
创建索引
{
"mappings": {
"properties": {
"my_signed_integer": {
"type":"integer",
"null_value": -1 --> note we defining `null` values as `-1`.
}
}
}
}
索引文件
存储null
整数文档
{
"my_number":空
}
如果您从 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`.
}
}
索引非负值
{
"my_number":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
}
}
]
我有一个 SQL table 正在导出到 Elasticsearch。
其中一列是可以为 null 的数字字段,在某些记录中有 null。
当我们尝试索引 table 时,我们得到这个错误:
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')}}}])
如何让系统识别空值?
您正在处理一个常见的 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 时不会影响文档。
用户 WittyID,错过了一些重要的事情,例如:
null_value
的值必须与您的字段具有相同的数据类型,因此在他的示例中,他声明了integer
字段但将NULL
定义为null_values
, 会抛出json_parse_exception
并且这在 official link 中被称为important
如下:
The null_value needs to be the same data type as the field. For instance, a long field cannot have a string null_value.
null_value
仅影响数据的索引方式,它不会修改 _source 文档,因此在您的源文档中,无论您传递什么,都将被存储,而不是提到的那个在null_values
参数和查询时,您还需要使用值null_value
参数。.
简而言之,ES 无法识别 null
,因此您可以为 null
定义自定义值,然后使用它来索引和查询 null
values.It 使用下面的示例很容易解释整个事情,任何人都可以尝试:
创建索引
{
"mappings": {
"properties": {
"my_signed_integer": {
"type":"integer",
"null_value": -1 --> note we defining `null` values as `-1`.
}
}
}
}
索引文件
存储
null
整数文档{ "my_number":空 }
如果您从 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`.
}
}
索引非负值
{ "my_number":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
}
}
]