如何使用Elastic Search Java API设置父/子关系?

时间:2016-08-24 21:10:17

标签: java elasticsearch parent-child

我正在尝试使用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形成父/子关系的弹性文档?

2 个答案:

答案 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之间的父子关系,同时仍允许您动态映射其他属性。确保首先添加子映射,否则它将无法正常工作。