[英]Spring elastic : What is the correct way of using nested fields?
我對 ElasticSearch 很陌生。 我正在做一個項目,我們需要搜索包含一組兩個(OfferTranslation)的 object(Offer)。 目標是基於一些Offer領域,以及很多OfferTranslation領域進行研究。 這是兩個類的縮小版本:
Offer.class (請注意,我用 @Field(type= FieldType.Nested) 注釋了 Set 以便我可以進行嵌套查詢,如官方文檔中所述) :
@org.springframework.data.elasticsearch.annotations.Document(indexName = "offer")
@DynamicMapping(DynamicMappingValue.False)
public class Offer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@Field(type = FieldType.Long)
private Long id;
@OneToMany(mappedBy = "offer", targetEntity = OfferTranslation.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@JsonIgnoreProperties(
value = { "pictures", "videos", "owner", "contexts", "offer", "personOfInterests", "followers" },
allowSetters = true
)
@Field(type = FieldType.Nested, store = true)
private Set<OfferTranslation> offersTranslations = new HashSet<>();
}
報價翻譯.class:
@DynamicMapping(DynamicMappingValue.False)
public class OfferTranslation implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@Field(type = FieldType.Long)
private Long id;
@NotNull
@Size(max = 100)
@Column(name = "title", length = 100, nullable = false)
@Field(type = FieldType.Text)
private String title;
@NotNull
@Size(max = 2000)
@Column(name = "summary", length = 2000, nullable = false)
@Field(type = FieldType.Text)
private String summary;
@Size(max = 2000)
@Column(name = "competitor_context", length = 2000)
@Field(type = FieldType.Text)
private String competitorContext;
@NotNull
@Size(max = 2000)
@Column(name = "description", length = 2000, nullable = false)
@Field(type = FieldType.Text)
private String description;
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "maturity", nullable = false)
@Field(type = FieldType.Auto)
private RefMaturity maturity;
@ManyToOne
@Field(type = FieldType.Object, store = true)
private RefLanguage language;
@NotNull
@Column(name = "created_at", nullable = false)
@Field(type = FieldType.Date)
private Instant createdAt;
}
預期的行為是我可以這樣進行nestedQueries:
QueryBuilder qBuilder = nestedQuery("offersTranslations",boolQuery().must(termQuery("offersTranslations.language.code",language)), ScoreMode.None);
但我得到的是一個例外:未能創建查詢:[nested] 路徑 [offersTranslations] 下的嵌套 object 不是嵌套類型”
編輯:我可以使用普通查詢訪問 offerTranslations.language.code(目前這並沒有真正打擾我)。 但我還是不太明白。
我的映射說字段 offerTranslations 不是嵌套類型,如您在上面看到的,但是由於我使用了 @Field(type = FieldType.Nested) 我並不真正理解這種行為。 有人可以解釋一下嗎?
{
"offer" : {
"mappings" : {
"properties" : {
"_class" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"categories" : {
"properties" : {
"id" : {
"type" : "long"
}
}
},
"criteria" : {
"properties" : {
"id" : {
"type" : "long"
}
}
},
"id" : {
"type" : "long"
},
"keywords" : {
"properties" : {
"id" : {
"type" : "long"
}
}
},
"offersTranslations" : {
"properties" : {
"competitorContext" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"createdAt" : {
"type" : "date"
},
"description" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"id" : {
"type" : "long"
},
"language" : {
"properties" : {
"code" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"id" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"maturity" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"state" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"summary" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"updatedAt" : {
"type" : "date"
}
}
},
"units" : {
"properties" : {
"id" : {
"type" : "long"
}
}
}
}
}
}
}
索引映射是如何創建的? 它看起來不像 Spring 數據 Elasticsearch 寫了這個映射。 如您所見, offerTranslations
的嵌套類型缺失,並且文本字段有一個.keyword
子字段。 這看起來像是在沒有定義映射的情況下將數據插入索引,因此 Elasticsearch 進行了自動映射。 在這種情況下,不使用@Field
注釋的值。
您需要讓 Spring 數據 Elasticsearch 使用映射創建索引。 如果索引不存在並且您正在使用 Spring 數據 Elasticsearch 存儲庫,這將自動發生,或者您需要在應用程序中使用IndexOperations.createWithMapping
ZC1C425268E68385D1AB5074C17A94F14。
我注意到的另一件事:似乎您對不同的 Spring 數據存儲使用相同的實體 class ,大量混合注釋。 您應該為不同的商店使用不同的實體。
解決步驟:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.