[英]Search in json field using hibernate search
我在使用 hibernate 搜索的实体进行搜索时遇到问题。 就我而言,我需要搜索:
这是我的实体:
@Entity
@Indexed(index = "test")
@Table(name = "test")
@TypeDef(name = "jsonb", typeClass = Jsonb.class)
public class TestEntity {
@Id
@Column(name = "id")
private UUID Id;
@FullTextField
@Column(name = "name", nullable = false, length = 50)
private String name;
@FullTextField
@Column(name = "desc")
private String desc;
@Column(name = "data")
@Type(type = "jsonb")
@ElementCollection
@PropertyBinding(binder = @PropertyBinderRef(type = JsonPropertyBinderNew.class))
private Map<String, Object> data;
//constructor
//getters
//setters
}
实体有一个 JSONB 格式的列。 使用 PropertyBinder 我将它保存在弹性中:
public class JsonPropertyBinder implements PropertyBinder {
@Override
public void bind(PropertyBindingContext context) {
context.dependencies().useRootOnly();
IndexSchemaElement schemaElement = context.indexSchemaElement();
IndexFieldType<String> amountFieldType = context.typeFactory()
.asString().analyzer("english").toIndexFieldType();
context.bridge(Map.class, new Bridge(
schemaElement.field("data", amountFieldType).toReference()));
}
private static class Bridge implements PropertyBridge<Map> {
private IndexFieldReference<String> data;
public Bridge(IndexFieldReference<String> data) {
this.data = data;
}
@Override
public void write(DocumentElement target, Map bridgedElement, PropertyBridgeWriteContext context) {
Gson gson = new Gson();
target.addValue(data, gson.toJson(bridgedElement));
}
}
在弹性中它看起来像:
data: {"SomeKey":"SomeKey","StringKey":"Stroka","ObjectKey":"ObjectData"}
desc:Fourth
name: Fourth Test Name
当我尝试按字段搜索时
List<TestEntity> result = searchSession.search(TestEntity.class)
.where(f -> f.exists().field("data.SomeKey"))
.fetchHits(20);
我得到了例外:“org.hibernate.search.util.common.SearchException:HSEARCH400504:未知字段'data.SomeKey'”
如果我尝试使用simpleQueryString
它可以工作,但我不能使用模糊测试:
SearchResult<TestEntity> search = searchSession.search(TestEntity.class)
.where(f -> f.simpleQueryString()
.fields("data")
.matching("ObjectKey + ObjectData")
).fetch(20);
如果我尝试使用 Predicate DSL,我不能使用 boolean 运算符,例如“AND using +”
List<TestEntity> hits = searchSession.search( TestEntity.class )
.where( f -> f.match().field( "data" )
.matching( "ObjectKey ObjectData" ).fuzzy())
.fetchHits( 20 );
我如何使用键值对内部 json 进行搜索?
如果您想使用 Hibernate Search DSL 进行搜索,您需要让 Hibernate Search 了解您的架构:字段、名称、类型、...
通过仅声明一个“数据”字段并将 JSON 直接推入其中,您实际上是从 Hibernate 搜索中隐藏了架构。 您还依赖于 Elasticsearch 在首次将字段类型填充到索引中时自动检测字段类型的能力,这可能会导致严重的意外。
当您这样做时,您唯一的搜索解决方案是绕过 Hibernate 搜索并自己写下查询的 JSON 。 请参阅此处了解 JSON 语法。 我个人会避免这种情况,但对每个人来说都是他自己的。
确实,更好的解决方案是使用字段模板干净地声明所有字段。 这样 Hibernate 搜索就会知道每个字段的类型,您就可以利用 DSL。
至于针对单个谓词中的所有字段,Hibernate 搜索尚不支持 ( HSEARCH-3926 )。 您必须:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.