Hibernate Search:在 ElasticSearch 上映射 IndexedEmbedded 会导致在映射中找不到 [] 的字段

Hibernate Search: mapping IndexedEmbedded on ElasticSearch causes No field found for [] in mapping

我有两个实体,SearchAmount,我正在使用 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);。我不确定这种语法是否完全正确,因为我找不到任何文档来按某种方式访问​​源代码,但它应该接近于此。另外,请记住,如果您有很多文档,这会很慢。

另请参阅: