首页 > 解决方案 > 当字符串作为参数传递时,ElasticSearch 2.3 geo_point 字段会引发错误

问题描述

我正在使用带有 NodeJs 14 的 Elasticsearch 2.3 版本。我试图分配 geo_point 的字符串版本,'41.00445520431176,28.976772329847574'而不是{ "lat": 41.12, "lon": -71.34 }抛出错误。

这是来自Nodejs的错误

StatusCodeError: [mapper_parsing_exception] failed to parse
  at respond (/usr/src/app/node_modules/elasticsearch/src/lib/transport.js:349:15)
  at checkRespForFailure (/usr/src/app/node_modules/elasticsearch/src/lib/transport.js:306:7)
  at HttpConnector.<anonymous> (/usr/src/app/node_modules/elasticsearch/src/lib/connectors/http.js:173:7)
  at IncomingMessage.wrapper (/usr/src/app/node_modules/lodash/lodash.js:4991:19)
  at IncomingMessage.emit (events.js:412:35)
  at IncomingMessage.emit (domain.js:537:15)
  at endReadableNT (internal/streams/readable.js:1334:12)
  at processTicksAndRejections (internal/process/task_queues.js:82:21) {
status: 400,
displayName: 'BadRequest',
path: '/users/_doc',
query: { type: 'user' },
body: {
  error: {
    root_cause: [Array],
    type: 'mapper_parsing_exception',
    reason: 'failed to parse',
    caused_by: [Object]
  },
  status: 400
},
statusCode: 400,
response: '{"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"failed to parse"}],"type":"mapper_parsing_exception","reason":"failed to parse","caused_by":{"type":"illegal_state_exception","reason":"Mixing up field types: class org.elasticsearch.index.mapper.core.StringFieldMapper$StringFieldType != class org.elasticsearch.index.mapper.geo.BaseGeoPointFieldMapper$GeoPointFieldType on field location"}},"status":400}',
toString: [Function (anonymous)],
toJSON: [Function (anonymous)]

这是在 docker 中运行的 Elasticsearch 2.3 的错误

 [2021-10-19 09:29:04,326][DEBUG][action.index             ] [Ghost Dancer] failed to execute [index {[users][_doc][AXyX4gRD7BhLOaBJFlNV], source[{"company_title":"eren-company","country":{"country_code":"tr","country_name":"eren-test","id":225},"createdAt":"2017-11-13T11:19:21+00:00","experience_level":"0","experience_month":0,"experiences":{},"first_name":"eren-test","id":1,"last_name":"eren-lastname","location":"41.00445520431176,28.976772329847574","user_type":"created.user_type"}]}] on [[users][3]]
 MapperParsingException[failed to parse]; nested: IllegalStateException[Mixing up field types: class org.elasticsearch.index.mapper.core.StringFieldMapper$StringFieldType != class org.elasticsearch.index.mapper.geo.BaseGeoPointFieldMapper$GeoPointFieldType on field location];
        at org.elasticsearch.index.mapper.DocumentParser.parseDocument(DocumentParser.java:154)
        at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:309)
        at org.elasticsearch.index.shard.IndexShard.prepareCreate(IndexShard.java:529)
        at org.elasticsearch.index.shard.IndexShard.prepareCreateOnPrimary(IndexShard.java:506)
        at org.elasticsearch.action.index.TransportIndexAction.prepareIndexOperationOnPrimary(TransportIndexAction.java:215)
        at org.elasticsearch.action.index.TransportIndexAction.executeIndexRequestOnPrimary(TransportIndexAction.java:224)
        at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:158)
        at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:66)
        at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryPhase.doRun(TransportReplicationAction.java:639)
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
        at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryOperationTransportHandler.messageReceived(TransportReplicationAction.java:279)
        at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryOperationTransportHandler.messageReceived(TransportReplicationAction.java:271)
        at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:75)
        at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:376)
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
 Caused by: java.lang.IllegalStateException: Mixing up field types: class org.elasticsearch.index.mapper.core.StringFieldMapper$StringFieldType != class org.elasticsearch.index.mapper.geo.BaseGeoPointFieldMapper$GeoPointFieldType on field location
        at org.elasticsearch.index.mapper.FieldMapper.updateFieldType(FieldMapper.java:397)
        at org.elasticsearch.index.mapper.FieldMapper.updateFieldType(FieldMapper.java:53)
        at org.elasticsearch.index.mapper.DocumentParser.parseDynamicValue(DocumentParser.java:622)
        at org.elasticsearch.index.mapper.DocumentParser.parseValue(DocumentParser.java:442)
        at org.elasticsearch.index.mapper.DocumentParser.parseObject(DocumentParser.java:262)
        at org.elasticsearch.index.mapper.DocumentParser.parseDocument(DocumentParser.java:122)
        ... 17 more

最后是来自 ElasticSearch 的映射。

{
    "users": {
        "mappings": {
            "user": {
                "_meta": {
                    "model": "AppBundle\\Entity\\User"
                },
                "properties": {
                    "company_title": {
                        "type": "string",
                        "boost": 5,
                        "analyzer": "turkishIcu"
                    },
                    "country": {
                        "properties": {
                            "country_code": {
                                "type": "string"
                            },
                            "country_name": {
                                "type": "string"
                            },
                            "id": {
                                "type": "integer"
                            }
                        }
                    },
                    "createdAt": {
                        "type": "date",
                        "format": "strict_date_optional_time||epoch_millis"
                    },
                    "experience_level": {
                        "type": "string",
                        "index": "not_analyzed"
                    },
                    "experience_month": {
                        "type": "integer"
                    },
                    "experiences": {
                        "properties": {
                            "company_name": {
                                "type": "string",
                                "boost": 5,
                                "analyzer": "turkishIcu"
                            },
                            "position": {
                                "type": "string",
                                "boost": 5
                            }
                        }
                    },
                    "first_name": {
                        "type": "string",
                        "boost": 10,
                        "analyzer": "turkishIcu"
                    },
                    "id": {
                        "type": "integer",
                        "boost": 0,
                        "norms": {
                            "enabled": true
                        }
                    },
                    "last_name": {
                        "type": "string",
                        "boost": 10,
                        "analyzer": "turkishIcu"
                    },
                    "location": {
                        "type": "geo_point"
                    },
                    "user_type": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

除了以上所有;当我尝试通过时,{ "lat": 41.12, "lon": -71.34 }我收到以下错误。

 StatusCodeError: [invalid_type_name_exception] Document mapping type name can't start with '_'
     at respond (/usr/src/app/node_modules/elasticsearch/src/lib/transport.js:349:15)
     at checkRespForFailure (/usr/src/app/node_modules/elasticsearch/src/lib/transport.js:306:7)
     at HttpConnector.<anonymous> (/usr/src/app/node_modules/elasticsearch/src/lib/connectors/http.js:173:7)
     at IncomingMessage.wrapper (/usr/src/app/node_modules/lodash/lodash.js:4991:19)
     at IncomingMessage.emit (events.js:412:35)
     at IncomingMessage.emit (domain.js:537:15)
     at endReadableNT (internal/streams/readable.js:1334:12)
     at processTicksAndRejections (internal/process/task_queues.js:82:21) {
   status: 400,
   displayName: 'BadRequest',
   path: '/users/_doc',
   query: { type: 'user' },
   body: {
     error: {
       root_cause: [Array],
       type: 'invalid_type_name_exception',
       reason: "Document mapping type name can't start with '_'"
     },
     status: 400
   },
   statusCode: 400,
   response: `{"error":{"root_cause":[{"type":"invalid_type_name_exception","reason":"Document mapping type name can't start with '_'"}],"type":"invalid_type_name_exception","reason":"Document mapping type name can't start with '_'"},"status":400}`,
   toString: [Function (anonymous)],
   toJSON: [Function (anonymous)]
 }

正如我之前所说;

谢谢您的帮助。

真诚的艾伦;

标签: node.jstypescriptelasticsearchelasticsearch-2.0

解决方案


我解决了这个问题。由于apiVersion切换到正确的版本解决了问题,因此出现了问题。

TL;博士;

import { Client } from 'elasticsearch';
this.client = new Client({
   host: configService.get<string>('ELASTICSEARCH_HOST'),
   apiVersion: '5.6',
});

我对包本身进行了一些研究,发现如果你没有指定apiVersion它会自动导入主 api 并且主 api 格式如下所示的 url,这是错误的。

  urls: [
    {
      fmt: '/<%=index%>/_doc/<%=id%>',
      req: {
        index: {
          type: 'string'
        },
        id: {
          type: 'string'
        }
      }
    },
    {
      fmt: '/<%=index%>/_doc',
      req: {
        index: {
          type: 'string'
        }
      }
    }
  ]

整个_doc问题都来自这种格式,它不关心映射名称。我认为这是一个错误。然后我检查了其他 api,它们如下所示;

  urls: [
    {
      fmt: '/<%=index%>/<%=type%>/<%=id%>',
      req: {
        index: {
          type: 'string'
        },
        id: {
          type: 'string'
        }
      }
    },
    {
      fmt: '/<%=index%>/<%=type%>',
      req: {
        index: {
          type: 'string'
        }
      }
    }
  ]

它们包括称为类型的映射名称。然后我指定立即修复apiVersionClient问题。


推荐阅读