Hibernate Search:在 ElasticSearch 上映射 IndexedEmbedded 会导致在映射中找不到 [] 的字段
Hibernate Search: mapping IndexedEmbedded on ElasticSearch causes No field found for [] in mapping
我有两个实体,Search
和 Amount
,我正在使用 Hibernate Search 以这种方式进行映射:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Entity
@Indexed
public class Search extends SearchableItem {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEARCH_SEQ")
@DocumentId
private Long id;
@Embedded
@Valid
@IndexedEmbedded
private Amount maxAmount;
@Embedded
@Valid
@IndexedEmbedded
private Amount minAmount;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Embeddable
public class Amount {
@NotNull
@ScaledNumberField(sortable = Sortable.YES)
private BigDecimal value;
@NotNull
@Enumerated(EnumType.STRING)
@GenericField
private CurrencyCode currency;
}
这些注释在 Elasticsearch 上以这种方式创建我的索引:
{
"search-000001": {
"aliases": {
"search-read": {
"is_write_index": false
},
"search-write": {
"is_write_index": true
}
},
"mappings": {
"dynamic": "strict",
"properties": {
"_entity_type": {
"type": "keyword",
"index": false
},
"maxAmount": {
"dynamic": "strict",
"properties": {
"currency": {
"type": "keyword",
"doc_values": false
},
"value": {
"type": "scaled_float",
"scaling_factor": 100
}
}
},
"minAmount": {
"dynamic": "strict",
"properties": {
"currency": {
"type": "keyword",
"doc_values": false
},
"value": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
},
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "search-000001",
"creation_date": "1644485712235",
"analysis": {
"normalizer": {
"sort": {
"filter": [
"asciifolding",
"lowercase"
],
"type": "custom"
}
},
"analyzer": {
"name": {
"filter": [
"asciifolding",
"lowercase"
],
"type": "custom",
"tokenizer": "standard"
},
"generic_text": {
"filter": [
"asciifolding",
"lowercase",
"porter_stem"
],
"type": "custom",
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"uuid": "GBfV36PLT2-JEVPlbE2DVw",
"version": {
"created": "7160399"
}
}
}
}
}
对于 Elasticsearch 上的搜索,我正在使用自定义评分函数来尝试访问搜索文档中的 minAmount 和 maxAmount 对象,但我收到此错误:
Unhandled Exception illegal_argument_exception
No field found for [maxAmount] in mapping
Stack:
[
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:100)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:28)",
"score += calculateScoreAmount(doc.maxAmount, doc.minAmount, params);\n ",
" ^---- HERE"
]
我过去在其他实体上遇到过同样的问题,我解决了它,在 属性 上指定 @GenericField(sortable = Sortable.YES)
我需要在评分脚本中访问(请注意,没有明确的 Sortable.YES 我在脚本评分函数执行期间收到来自 Elasticsearch 的错误)。这里的问题是 Amount
是自定义对象,无法在其上指定 @GenericField(sortable = Sortable.YES)
。
有人可以帮忙吗?
maxAmount
是一个对象字段。通过doc.maxAmount
取回它的值是没有意义的,因为这个语法是访问doc值的,对象字段不在doc值中表示。
我不确定您的脚本是什么或您将它传递给 Elasticsearch 的位置,但问题可能就在那里。
如果您想访问 maxAmount.value
/minAmount.value
的文档值,那么您可能应该将 calculateScoreAmount(doc.maxAmount, doc.minAmount, params);
替换为 calculateScoreAmount(doc['maxAmount.value'].value, doc['minAmount.value'].value, params);
如果要访问表示 maxAmount
/minAmount
的 JSON 对象,则不应使用文档值,而应使用 _source
: calculateScoreAmount(ctx._source.maxAmount, ctx._source.minAmount, params);
。我不确定这种语法是否完全正确,因为我找不到任何文档来按某种方式访问源代码,但它应该接近于此。另外,请记住,如果您有很多文档,这会很慢。
另请参阅:
我有两个实体,Search
和 Amount
,我正在使用 Hibernate Search 以这种方式进行映射:
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Entity
@Indexed
public class Search extends SearchableItem {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEARCH_SEQ")
@DocumentId
private Long id;
@Embedded
@Valid
@IndexedEmbedded
private Amount maxAmount;
@Embedded
@Valid
@IndexedEmbedded
private Amount minAmount;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
@Embeddable
public class Amount {
@NotNull
@ScaledNumberField(sortable = Sortable.YES)
private BigDecimal value;
@NotNull
@Enumerated(EnumType.STRING)
@GenericField
private CurrencyCode currency;
}
这些注释在 Elasticsearch 上以这种方式创建我的索引:
{
"search-000001": {
"aliases": {
"search-read": {
"is_write_index": false
},
"search-write": {
"is_write_index": true
}
},
"mappings": {
"dynamic": "strict",
"properties": {
"_entity_type": {
"type": "keyword",
"index": false
},
"maxAmount": {
"dynamic": "strict",
"properties": {
"currency": {
"type": "keyword",
"doc_values": false
},
"value": {
"type": "scaled_float",
"scaling_factor": 100
}
}
},
"minAmount": {
"dynamic": "strict",
"properties": {
"currency": {
"type": "keyword",
"doc_values": false
},
"value": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
},
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "search-000001",
"creation_date": "1644485712235",
"analysis": {
"normalizer": {
"sort": {
"filter": [
"asciifolding",
"lowercase"
],
"type": "custom"
}
},
"analyzer": {
"name": {
"filter": [
"asciifolding",
"lowercase"
],
"type": "custom",
"tokenizer": "standard"
},
"generic_text": {
"filter": [
"asciifolding",
"lowercase",
"porter_stem"
],
"type": "custom",
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"uuid": "GBfV36PLT2-JEVPlbE2DVw",
"version": {
"created": "7160399"
}
}
}
}
}
对于 Elasticsearch 上的搜索,我正在使用自定义评分函数来尝试访问搜索文档中的 minAmount 和 maxAmount 对象,但我收到此错误:
Unhandled Exception illegal_argument_exception
No field found for [maxAmount] in mapping
Stack:
[
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:100)",
"org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:28)",
"score += calculateScoreAmount(doc.maxAmount, doc.minAmount, params);\n ",
" ^---- HERE"
]
我过去在其他实体上遇到过同样的问题,我解决了它,在 属性 上指定 @GenericField(sortable = Sortable.YES)
我需要在评分脚本中访问(请注意,没有明确的 Sortable.YES 我在脚本评分函数执行期间收到来自 Elasticsearch 的错误)。这里的问题是 Amount
是自定义对象,无法在其上指定 @GenericField(sortable = Sortable.YES)
。
有人可以帮忙吗?
maxAmount
是一个对象字段。通过doc.maxAmount
取回它的值是没有意义的,因为这个语法是访问doc值的,对象字段不在doc值中表示。
我不确定您的脚本是什么或您将它传递给 Elasticsearch 的位置,但问题可能就在那里。
如果您想访问 maxAmount.value
/minAmount.value
的文档值,那么您可能应该将 calculateScoreAmount(doc.maxAmount, doc.minAmount, params);
替换为 calculateScoreAmount(doc['maxAmount.value'].value, doc['minAmount.value'].value, params);
如果要访问表示 maxAmount
/minAmount
的 JSON 对象,则不应使用文档值,而应使用 _source
: calculateScoreAmount(ctx._source.maxAmount, ctx._source.minAmount, params);
。我不确定这种语法是否完全正确,因为我找不到任何文档来按某种方式访问源代码,但它应该接近于此。另外,请记住,如果您有很多文档,这会很慢。
另请参阅: