我正在使用ES 7.2.1来存储大量基于位置的数据并查询附近的位置。对于位置坐标,我正在使用Java代码库中的GeoPoint字段。
ES:7.2.1Spring Data Elasticsearch:4.0.0.DATAES-690-SNAPSHOTMVN 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数据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.3Spring Data Elasticsearch:3.1.X
我能够(通过模板)插入带有GeoPoint字段的文档。通过代码插入doc时会自动生成索引。相同的代码集可以正常工作,没有错误!!!
这是我的模板:
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"
}
}
}
}
您显示的代码中有些东西不匹配:
在显示的第一个模板中,将storeName定义为类型keyword
,但是在实体上将其定义为类型text
。
用@Id
注释的字段始终是类型keyword
,忽略将其定义为@Field
类型的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"
}
}
}
}
}
映射看起来应该像它,映射中有no类型信息(这是在使用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_name现在是keyword
类型,来自模板):
{
"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"
}
}
]
}
}
所以我无法在代码中找到错误,但是如果有冲突的条目,则应检查模板和现有索引。