如何为自定义对象列表声明嵌套字段类型?

时间:2019-06-14 19:53:12

标签: object elasticsearch nested

我有一个用SearchFields嵌套类型定义的类。我可以保存文档,但是在使用repository.findAll()进行检索时出现错误:org.springframework.data.elasticsearch.ElasticsearchException: failed to map source [ {"id":"P2_P2","parentId":"P2","searchFieldsList":[{"id": "N2", "sender":false,"domains":[]}]}] to class MyFlags

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.SearchFields` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":"P2_P2","parentId":"P2","searchFields":[{"id":"N2","sender":false,"domains":[]}]}"; line: 1, column: 58] (through reference chain: com.MyFlags["searchFields"]->java.util.ArrayList[0])
@Document(indexName = "#{@myIndexName}", type = SearchConstants.MY_TYPE)
@Setting(settingPath = SearchConstants.MY_INDEX_SETTINGS_PATH)
public class MyFlags {

    @Id
    private String id;

    @Parent(type = SearchConstants.DOCUMENT_TYPE)
    private String parentId;

    @Field(type = FieldType.Nested)
    private List<SearchFields> searchFieldsList;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setId(String id) {
        this.id = id;
    }

    public MyFlags() {
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    public String getParentId() {
        return parentId;
    }

    public List<SearchFields> getSearchFieldsList() {
        return searchFieldsList;
    }

    public void setSearchFieldsList(List<SearchFields> searchFieldsList) {
        this.searchFieldsList = searchFieldsList;
    }
}

SearchFields类是:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class SearchFields extends Serializable {

    @Field(type = FieldType.Keyword)
    private String id;

    @Field(type = FieldType.Boolean)
    private boolean sender;

    @Field(type = FieldType.Keyword)
    private Set<String> domains;

    public EmailChainSearchFields(String id) {
        this.id = id;
    }

    public String getSender() {
        return sender;
    }

    public void setSender(boolean senderDomain) {
        this.senderDomain = senderDomain;
    }

    public Set<String> getDomains() {
        return domains;
    }

    public void setDomains(Set<String> domains) {
        this.domains = Sets.newHashSet();
    }
}

在kibana上显示的映射是

{
  "my_index_name": {
    "aliases": {},
    "mappings": {
      "my_flags": {
        "_parent": {
          "type": "document_type"
        },
        "_routing": {
          "required": true
        },
        "properties": {
          "searchFieldsList": {
            "type": "nested",
            "properties": {
              "sender": {
                "type": "boolean"
              },
              "domains": {
                "type": "keyword"
              }
            }
          }
      }
   }
}

我在线阅读的示例(包括SO)未定义列表。仅定义了一个对象来代替searchFieldsList。所以我想知道这也许是我出问题的地方。

EDIT1:

匹配my_type类型的kibana中的所有查询结果

{
        "_index": "my_index_name",
        "_type": "my_type",
        "_id": "P1_P1",
        "_score": 1,
        "_routing": "P1",
        "_parent": "P1",
        "_source": {
          "id": "P1_P1",
          "parentId": "P1",
          "emailChainSearchFields": [
            {
              "id": "N4",
              "sender": false,
              "domains": [
                "wahtever.com"
              ],
            },
            {
              "id": "N1",
              "sender": true,
              "domains": [
                "google.com"
              ]
            }
          ]
        }
      }

1 个答案:

答案 0 :(得分:1)

嵌套对象是否将成为唯一成员?如果是这样,那么我不确定此映射将为您提供什么价值。您只需拥有一个“ searchFields”文档类型即可。

此外,映射中嵌套字段的名称应针对单个文档,即searchFields。父文档中将包含多个这些嵌套文档。

最后,一个可能的解决方案:SearchFields类具有“ id”作为成员,而映射中的嵌套对象则没有。另外,您将需要更改映射(searchFieldsList-> searchFields)。进行这些更改后,请重试。

还要确保每个实体(主文档和嵌套文档,都有)都有默认的构造函数。