0

我正在使用 ES 7.2.1 存储大量基于位置的数据并查询附近的位置。对于位置坐标,我使用我的 java 代码库中的 GeoPoint 字段。

ES:7.2.1
Spring Data Elasticsearch:4.0.0.DATAES-690-SNAPSHOT
MVN org.elasticsearch:7.2.1

模板:

curl -X PUT "localhost:9200/_template/store_locator_template?pretty"
{
  "order": 1,
  "index_patterns": [
    "store_locator_*"
  ],
  "settings": {
  },
  "mappings": {
      "properties": {
      "esId": {
        "type": "keyword"
      },
      "geoPoint": {
        "type": "geo_point"
      },
      "storeName": {
        "type": "keyword"
      }
    }
  }
}

尝试通过 bulkIndex() 插入数据时,出现此错误:

org.springframework.data.elasticsearch.ElasticsearchException: 
Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() 
for detailed messages [{QObQeXEBqxAg6uMFyeNZ=ElasticsearchException
[Elasticsearch exception 
[type=illegal_argument_exception, reason=
mapper [geoPoint] of different type, 
current_type [geo_point], merged_type [ObjectMapper]]]}]

实体:

@Getter
@Setter
@ToString
@EqualsAndHashCode(of = "esId", callSuper = false)
@NoArgsConstructor
@Document(indexName = "store_locator_index", replicas = 0, createIndex = false)
public class EsEntity {

  @Id
  @Field(type = FieldType.Text)
  private String esId;

  @GeoPointField
  private GeoPoint geoPoint;

  @Field(type = FieldType.Text)
  private String storeName;
}

更新:如果我使用下面的代码,它工作正常。它根据需要放置映射,并且 spring data es 没有抱怨!

//clazz -> entity class with @Document annotation

boolean indexCreated = false;
if (!elasticsearchOperations.indexExists(clazz)) {
    indexCreated = elasticsearchOperations.createIndex(clazz);
}
if (indexCreated) {
    elasticsearchOperations.refresh(clazz);
    elasticsearchOperations.putMapping(clazz);   --> Does the MAGIC
}

...从上面的代码生成的映射是:

{
   "esentity":{              ---> Why is this here??
      "properties":{
         "esId":{
            "type":"keyword",
            "index":true
         },
         "geoPoint":{
            "type":"geo_point"
         }
      }
   }
}

它正在以我的实体类的名称向映射添加一个类型!

=====================
还.....

一切似乎都适用于:
ES:6.4.3
Spring Data Elasticsearch:3.1.X

我能够(通过模板)插入带有 GeoPoint 字段的文档。通过代码插入文档时会自动生成索引。同一组代码工作正常,没有错误!!!!

这是我的模板:

curl -X PUT "localhost:9200/_template/store_locator_template?pretty"
{
  "order": 1,
  "index_patterns": [
    "store_locator_*"
  ],
  "settings": {
  },
  "mappings": {
    "store_locator_index": {
      "properties": {
      "esId": {
        "type": "keyword"
      },
      "geoPoint": {
        "type": "geo_point"
      },
      "storeName": {
        "type": "keyword"
      }
    }
   }
  }
}

这是映射:

{
  "mapping": {
    "properties": {
      "esId": {
        "type": "keyword"
      },
      "geoPoint": {
        "type": "geo_point"
      }
    }
  }
}
4

1 回答 1

0

您显示的代码中有一些不匹配的内容:

在您展示的第一个模板中,您将storeName定义为 type keyword,但在实体上您将其定义为 type text

带有注释的字段@Id始终是 type keyword,将其@Field定义为 type 的注释将text被忽略。

我使用了以下版本:ES 7.3.0(我的机器上没有 7.2.1),Spring Data 4.0 当前主版本,客户端库设置为 7.3.0。

当我没有定义模板,但使用您显示的代码创建索引时:

    boolean indexCreated = false;

    Class<EsEntity> clazz = EsEntity.class;
    if (!elasticsearchOperations.indexExists(clazz)) {
        indexCreated = elasticsearchOperations.createIndex(clazz);
    }
    if (indexCreated) {
        elasticsearchOperations.refresh(clazz);
        elasticsearchOperations.putMapping(clazz);
    }

我得到以下索引:

{
  "store_locator_index": {
    "aliases": {},
    "mappings": {
      "properties": {
        "esId": {
          "type": "keyword"
        },
        "geoPoint": {
          "type": "geo_point"
        },
        "storeName": {
          "type": "text"
        }
      }
    },
    "settings": {
      "index": {
        "refresh_interval": "1s",
        "number_of_shards": "1",
        "provided_name": "store_locator_index",
        "creation_date": "1587073075464",
        "store": {
          "type": "fs"
        },
        "number_of_replicas": "0",
        "uuid": "72aZqWDtS7KLDMwdkgVtag",
        "version": {
          "created": "7030099"
        }
      }
    }
  }
}

映射看起来应该,映射中没有类型信息(这是使用 ES 6 时由 Spring Data Elasticsearch 3.2 版本编写的,但我不再使用)

当我添加您显示的模板,然后使用以下代码进行批量插入时:

    EsEntity es1 = new EsEntity();
    es1.setEsId("1");
    es1.setGeoPoint(new GeoPoint(12, 34));
    es1.setStoreName("s1");
    IndexQuery query1 = new IndexQueryBuilder().withId("1").withObject(es1).build();

    EsEntity es2 = new EsEntity();
    es2.setEsId("2");
    es2.setGeoPoint(new GeoPoint(56, 78));
    es2.setStoreName("s2");
    IndexQuery query2 = new IndexQueryBuilder().withId("2").withObject(es2).build();

    elasticsearchOperations.bulkIndex(Arrays.asList(query1, query2), IndexCoordinates.of("store_locator_index"));

然后创建以下索引(注意 store_namekeyword现在是类型,来自模板):

{
  "store_locator_index": {
    "aliases": {},
    "mappings": {
      "properties": {
        "_class": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "esId": {
          "type": "keyword"
        },
        "geoPoint": {
          "type": "geo_point"
        },
        "storeName": {
          "type": "keyword"
        }
      }
    },
    "settings": {
      "index": {
        "creation_date": "1587073540386",
        "number_of_shards": "1",
        "number_of_replicas": "1",
        "uuid": "LqzXMC5uRmKmImIzblFBOQ",
        "version": {
          "created": "7030099"
        },
        "provided_name": "store_locator_index"
      }
    }
  }
}

并按原样插入这两个文件:

{
  "took": 22,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "store_locator_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "_class": "com.sothawo.springdataelastictest.EsEntity",
          "esId": "1",
          "geoPoint": {
            "lat": 12.0,
            "lon": 34.0
          },
          "storeName": "s1"
        }
      },
      {
        "_index": "store_locator_index",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "_class": "com.sothawo.springdataelastictest.EsEntity",
          "esId": "2",
          "geoPoint": {
            "lat": 56.0,
            "lon": 78.0
          },
          "storeName": "s2"
        }
      }
    ]
  }
}

所以我在代码中找不到错误,但如果有冲突的条目,你应该检查模板和现有索引。

于 2020-04-16T21:53:07.440 回答