使用键作为字段名称索引 HashMap。休眠搜索
Index HashMap using keys as fields names. HibernateSearch
我想通过使用映射键作为字段名称来索引 map<String, Integer>
。我发现默认情况下我只能索引键或值 (BuiltinContainerExtractors.MAP_KEY/MAP_VALUES
),所以我正在尝试实现我自己的 binder/bridge。那是我的代码:
public class SomeEntity {
@Transient
@PropertyBinding(binder = @PropertyBinderRef(type = ConceptDistancePropertyBinder.class))
public Map<String, Integer> getRelated() {
return ...;
}
}
public class ConceptDistancePropertyBinder implements PropertyBinder {
@Override
public void bind(PropertyBindingContext context) {
context.dependencies().useRootOnly();
IndexSchemaElement schemaElement = context.indexSchemaElement();
IndexSchemaObjectField conceptDistanceField = schemaElement.objectField("conceptDistance");
conceptDistanceField.fieldTemplate(
"conceptDistanceTemplate",
fieldTypeFactory -> fieldTypeFactory.asString().analyzer("default")
);
final ConceptDistancePropertyBridge bridge = new ConceptDistancePropertyBridge(conceptDistanceField.toReference());
context.bridge(Map.class, bridge);
}
}
public class ConceptDistancePropertyBridge implements PropertyBridge<Map> {
private final IndexObjectFieldReference conceptDistanceFieldReference;
public ConceptDistancePropertyBridge(IndexObjectFieldReference conceptDistanceFieldReference) {
this.conceptDistanceFieldReference = conceptDistanceFieldReference;
}
@Override
public void write(DocumentElement target, Map bridgedElement, PropertyBridgeWriteContext context) {
Map<String, Integer> relatedDistanceWithOtherConcepts = (Map<String, Integer>) bridgedElement;
DocumentElement indexedUserMetadata = target.addObject(conceptDistanceFieldReference);
relatedDistanceWithOtherConcepts
.forEach((field, value) -> indexedUserMetadata.addValue(field, field));
}
}
我有一个例外:
Hibernate ORM mapping:
type 'com.odysseusinc.prometheus.concept.entity.ConceptEntity':
failures:
- HSEARCH800007: Unable to resolve path '.related' to a persisted attribute in Hibernate ORM metadata. If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information.
context.dependencies().useRootOnly()
没有帮助。我也尝试使用 context.dependencies().use("somefield")
但又遇到了另一个异常
Hibernate ORM mapping:
type 'com.odysseusinc.prometheus.concept.entity.ConceptEntity':
path '.related':
failures:
- HSEARCH700078: No readable property named 'filedName' on type 'java.lang.Integer'
我提取了所有必要的代码并将其放入 GitHub https://github.com/YaroslavTir/map-index
真的很简单,启动后出现异常 Application.main
正如错误信息告诉您的那样:
If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information.
具体参见 this section。
简而言之,将注释添加到 getRelated()
以便 Hibernate Search 知道您从哪些属性派生地图:
public class SomeEntity {
@Transient
@PropertyBinding(binder = @PropertyBinderRef(type = ConceptDistancePropertyBinder.class))
@IndexingDependency(
derivedFrom = {
@ObjectPath(@PropertyValue(propertyName = "someProperty1")),
@ObjectPath({@PropertyValue(propertyName = "someProperty2"), @PropertyValue(propertyName = "someNestedProperty")})
},
extraction = @ContainerExtraction(extract = ContainerExtract.NO)
)
public Map<String, Integer> getRelated() {
return ...;
}
}
请注意,在您的情况下,您必须在 @IndexingDependency
中明确指定 整个地图 是“派生的”,而不仅仅是值(这是 Hibernate如您所见,搜索将默认定位)。这就是您需要 extraction = @ContainerExtraction(extract = ContainerExtract.NO)
的原因:这实际上告诉 Hibernate Search“此元数据适用于整个地图,而不仅仅是值”。
我想通过使用映射键作为字段名称来索引 map<String, Integer>
。我发现默认情况下我只能索引键或值 (BuiltinContainerExtractors.MAP_KEY/MAP_VALUES
),所以我正在尝试实现我自己的 binder/bridge。那是我的代码:
public class SomeEntity {
@Transient
@PropertyBinding(binder = @PropertyBinderRef(type = ConceptDistancePropertyBinder.class))
public Map<String, Integer> getRelated() {
return ...;
}
}
public class ConceptDistancePropertyBinder implements PropertyBinder {
@Override
public void bind(PropertyBindingContext context) {
context.dependencies().useRootOnly();
IndexSchemaElement schemaElement = context.indexSchemaElement();
IndexSchemaObjectField conceptDistanceField = schemaElement.objectField("conceptDistance");
conceptDistanceField.fieldTemplate(
"conceptDistanceTemplate",
fieldTypeFactory -> fieldTypeFactory.asString().analyzer("default")
);
final ConceptDistancePropertyBridge bridge = new ConceptDistancePropertyBridge(conceptDistanceField.toReference());
context.bridge(Map.class, bridge);
}
}
public class ConceptDistancePropertyBridge implements PropertyBridge<Map> {
private final IndexObjectFieldReference conceptDistanceFieldReference;
public ConceptDistancePropertyBridge(IndexObjectFieldReference conceptDistanceFieldReference) {
this.conceptDistanceFieldReference = conceptDistanceFieldReference;
}
@Override
public void write(DocumentElement target, Map bridgedElement, PropertyBridgeWriteContext context) {
Map<String, Integer> relatedDistanceWithOtherConcepts = (Map<String, Integer>) bridgedElement;
DocumentElement indexedUserMetadata = target.addObject(conceptDistanceFieldReference);
relatedDistanceWithOtherConcepts
.forEach((field, value) -> indexedUserMetadata.addValue(field, field));
}
}
我有一个例外:
Hibernate ORM mapping:
type 'com.odysseusinc.prometheus.concept.entity.ConceptEntity':
failures:
- HSEARCH800007: Unable to resolve path '.related' to a persisted attribute in Hibernate ORM metadata. If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information.
context.dependencies().useRootOnly()
没有帮助。我也尝试使用 context.dependencies().use("somefield")
但又遇到了另一个异常
Hibernate ORM mapping:
type 'com.odysseusinc.prometheus.concept.entity.ConceptEntity':
path '.related':
failures:
- HSEARCH700078: No readable property named 'filedName' on type 'java.lang.Integer'
我提取了所有必要的代码并将其放入 GitHub https://github.com/YaroslavTir/map-index
真的很简单,启动后出现异常 Application.main
正如错误信息告诉您的那样:
If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information.
具体参见 this section。
简而言之,将注释添加到 getRelated()
以便 Hibernate Search 知道您从哪些属性派生地图:
public class SomeEntity {
@Transient
@PropertyBinding(binder = @PropertyBinderRef(type = ConceptDistancePropertyBinder.class))
@IndexingDependency(
derivedFrom = {
@ObjectPath(@PropertyValue(propertyName = "someProperty1")),
@ObjectPath({@PropertyValue(propertyName = "someProperty2"), @PropertyValue(propertyName = "someNestedProperty")})
},
extraction = @ContainerExtraction(extract = ContainerExtract.NO)
)
public Map<String, Integer> getRelated() {
return ...;
}
}
请注意,在您的情况下,您必须在 @IndexingDependency
中明确指定 整个地图 是“派生的”,而不仅仅是值(这是 Hibernate如您所见,搜索将默认定位)。这就是您需要 extraction = @ContainerExtraction(extract = ContainerExtract.NO)
的原因:这实际上告诉 Hibernate Search“此元数据适用于整个地图,而不仅仅是值”。