我正在尝试使用Elastic Search Java API创建两个文档,一个构建另一个文档的子项。
我的代码看起来像这样:
public void createRecord(Road road, Car car) throws Exception{
ObjectMapper objectMapper = new ObjectMapper();
String roadJson = objectMapper.writeValueAsString(road);
String carJson = objectMapper.writeValueAsString(car);
Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
IndexResponse response = client.prepareIndex("myIndex", "roadType").setSource(roadJson).get();
client.prepareIndex("myIndex", "carType").setParent(response.getId()).setSource(carJson).get();
}
此代码成功创建道路文档但是当它创建汽车文档时,我收到错误:
java.lang.IllegalArgumentException:如果没有父级,则无法指定父级 字段已配置
如何正确创建两个与ES Java API形成父/子关系的弹性文档?
答案 0 :(得分:2)
您似乎没有配置“carType”映射以将“roadType”指定为父级。
"mappings": {
"roadType": {
"properties": {
}
},
"carType": {
"_parent": {
"type": "roadType"
},
"properties": {
"make": {
"type": "string"
},
"model": {
"type": "string"
}
}
}
}
有关详细信息,请参阅此处:https://www.elastic.co/guide/en/elasticsearch/guide/current/parent-child-mapping.html
答案 1 :(得分:0)
我必须为父/子关系创建一个自定义映射器。这仍然保留了文档创建时可能发生的动态映射。
public void createRecord(Road road, Car car) throws Exception{
ObjectMapper objectMapper = new ObjectMapper();
String roadJson = objectMapper.writeValueAsString(road);
String carJson = objectMapper.writeValueAsString(car);
Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
if(!client.admin().indices().prepareExists("myIndex").get().isExists()){
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject().startObject("roadType").endObject().endObject();
XContentBuilder xContentBuilder2 = XContentFactory.jsonBuilder().startObject().startObject("carType").startObject("_parent").field("type", "roadType").endObject().endObject().endObject();
client.admin().indices().create(new CreateIndexRequest("myIndex")).get();
client.admin().indices().preparePutMapping("myIndex").setType("carType").setSource(xContentBuilder2).get();
client.admin().indices().preparePutMapping("myIndex").setType("roadType").setSource(xContentBuilder).get();
}
IndexResponse response = client.prepareIndex("myIndex", "roadType").setSource(roadJson).get();
client.prepareIndex("myIndex", "carType").setParent(response.getId()).setSource(carJson).get();
}
这将创建一个自定义映射器,用于设置roadType和carType之间的父子关系,同时仍允许您动态映射其他属性。确保首先添加子映射,否则它将无法正常工作。