Как отобразить тип соединения с помощью Spring DataasticSearch - PullRequest
0 голосов
/ 06 ноября 2018

я переиндексирую данные с es 2.4 до 5.6.
данные в es 2.4 имеют 2 типа, а тип 2 - это отношение родитель-потомок.
если переиндексировать его в es 5.6, индекс содержит только один тип, отношение родитель-потомок, используя тип соединения для разрешения.
данные выше работают нормально. Пример отображения, подобный этому, содержит тип соединения:

"mappings": {
    "doc": {
        "properties": {
            "my_join_field": {
                "eager_global_ordinals": true,
                "type": "join",
                "relations": {
                    "question": "answer"
                }
            },
            "name": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "ignore_above": 256,
                        "type": "keyword"
                    }
                }
            }
        }
    }
}

как отобразить тип соединения с помощью Spring DataasticSearch: в старой версии кода 2.4, я могу отобразить это так:

@Document(indexName = ParentEntity.INDEX, type = ParentEntity.PARENT_TYPE, shards = 1, replicas = 0, refreshInterval = "-1")
public class ParentEntity {

    public static final String INDEX = "parent-child";
    public static final String PARENT_TYPE = "parent-entity";
    public static final String CHILD_TYPE = "child-entity";

    @Id
    private String id;
    @Field(type = FieldType.Text, store = true)
    private String name;

    public ParentEntity() {
    }

    public ParentEntity(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return new ToStringCreator(this).append("id", id).append("name", name).toString();
    }

    @Document(indexName = INDEX, type = CHILD_TYPE, shards = 1, replicas = 0, refreshInterval = "-1")
    public static class ChildEntity {

        @Id
        private String id;
        @Field(type = FieldType.Text, store = true)
        @Parent(type = PARENT_TYPE)
        private String parentId;
        @Field(type = FieldType.Text, store = true)
        private String name;

        public ChildEntity() {
        }

        public ChildEntity(String id, String parentId, String name) {
            this.id = id;
            this.parentId = parentId;
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public String getParentId() {
            return parentId;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return new ToStringCreator(this).append("id", id).append("parentId", parentId).append("name", name).toString();
        }
    }
}

как я могу сопоставить тип соединения с помощью spring dataasticSearch v3.0.10?

Сегодня я попробовал приведенную ниже сущность к работе с данными эластичности пружины 3.0.10:

@Document(indexName = "join_index", type = "join_mapping")
@Data
public class JoinEntity {
    @Id
    private String id;
    @Mapping(mappingPath = "/mappings/join_type.json")
    private Map<String,String> relationType;
    @Field(type = FieldType.Keyword)
    private String name;
    //@Parent(type = "question")
    @Field(type = FieldType.Keyword)
    private String parentId;
}

join_type.json ниже:

{
  "type": "join",
  "relations": {
    "question": "answer"
  }
}

это создаст индекс и поставит работу отображения нормально:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
public class ElasticsearchTemplateJoinTests {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Before
    public void before() {
        clean();
        elasticsearchTemplate.deleteIndex(JoinEntity.class);
        elasticsearchTemplate.createIndex(JoinEntity.class);
        elasticsearchTemplate.putMapping(JoinEntity.class);
        elasticsearchTemplate.refresh(JoinEntity.class);
    }

    @Test
    public void shouldCreateIndexAndMappingSuccess(){
        Map mapping = elasticsearchTemplate.getMapping(JoinEntity.class);
        assertThat(mapping, is(notNullValue()));

        Map properties = (Map) mapping.get("properties");
        assertThat(properties, is(notNullValue()));

        assertThat(properties.containsKey("name"), is(true));
        Map file = (Map) properties.get("relationType");
        assertThat(file, is(notNullValue()));
        assertThat(((String) file.get("type")), is("join"));
    }
}

когда родительский индекс тоже работает нормально, но дочерний индекс выдает исключение:

@Test 
public void shouldIndexParentAndChildSuccess(){
    JoinEntity parenEntity = new JoinEntity();
    parenEntity.setName("parent_name");
    parenEntity.setRelationType(Collections.singletonMap("name","question"));
    IndexQuery parentQuery = new IndexQueryBuilder().withId("11").withObject(parenEntity).build();
    final String id = elasticsearchTemplate.index(parentQuery);
    assertThat("11",is(id));
    JoinEntity childEntity = new JoinEntity();
    childEntity.setName("child_name");
    Map<String,String> joinRelation = new HashMap<>(2);
    joinRelation.put("name","answer");
    joinRelation.put("parent", "11");
    childEntity.setRelationType(joinRelation);
    childEntity.setParentId("11");
    IndexQuery childQuery = new IndexQueryBuilder().withId("22").withObject(childEntity).build();
    elasticsearchTemplate.index(childQuery);
}

исключение:

MapperParsingException[failed to parse
]; nested: IllegalArgumentException[[routing] is missing for join field [relationType]];
    at org.elasticsearch.index.mapper.DocumentParser.wrapInMapperParsingException(DocumentParser.java:171)

как я могу решить эту проблему или правильно сопоставить новую версию родительско-дочерних отношений? Thks !!

...