[英]Hibernate Search Order by Collection Count within Date Range
我有两个对象-一个Document
对象和一个Hit
对象:
Document
id
description
hits (Collection of type Hits)
...
Hit
documentId (Type Document)
date
...
我正在尝试创建一个Hibernate Search查询,该查询搜索文档描述,然后根据给定日期范围内的命中次数对结果进行排序。
我在解决此问题时遇到了一些麻烦。 我已经采取一看这个 ,但考虑到点击的总数,并且不允许动态日期范围查询,桥接字段更新日期无关的。
我目前对我的Document
对象有一个索引,可以在description
正常工作。 我在想可能需要为Hit
对象创建一个索引,针对它的日期范围(按documentId
分组)运行一个查询,然后使用针对Document
索引的搜索词运行第二个查询。
有了这种策略,我仍然不确定如何:
documentId
对点击进行分组 我的猜测是,我需要从Hits
索引中获取所有结果(是否使用某种类型的构面逻辑进行分组/排序?),然后匹配documentId
/ term并在第二个查询中处理分页。 我只是不确定在使用QueryBuilder接口构建查询时,或者在没有想到的完全不同方法的情况下,这一切会如何。
更新
public class DateRangeDownloadsFieldComparator extends FieldComparator<Integer> {
class DownloadsParser implements FieldCache.IntParser {
@Override
public int parseInt(String string) {
/*
* What do I pass here and what do I do with it?
* Ideally, I would pass the downloads collection and return the size of the
* collection where the download appears within the provided date range, but
* passing a collection here does nothing, as it's silently ignored.
*/
return 0;
}
}
private Calendar startDate;
private Calendar endDate;
private final int[] fieldValues;
private int bottom;
private int[] currentReaderValues;
public DateRangeDownloadsFieldComparator(int numHits, Calendar startDate, Calendar endDate) {
super();
this.startDate = startDate;
this.endDate = endDate;
fieldValues = new int[numHits];
}
@Override
public int compare(int slot1, int slot2) {
return compareValues(fieldValues[slot1], fieldValues[slot2]);
}
@Override
public int compareBottom(int doc) throws IOException {
int currentDoc = currentReaderValues[doc];
return compareValues(bottom, currentDoc);
}
@Override
public int compareValues(Integer v1, Integer v2) {
if (v1 > v2) {
return 1;
}
else if (v1 < v2) {
return -1;
}
else {
return 0;
}
}
@Override
public void copy(int slot, int doc) throws IOException {
int v1 = currentReaderValues[doc];
fieldValues[slot] = v1;
}
@Override
public void setBottom(int slot) {
bottom = fieldValues[slot];
}
@Override
public void setNextReader(IndexReader reader, int docBase) throws IOException {
currentReaderValues = FieldCache.DEFAULT
.getInts(reader, "downloads", new DownloadsParser());
}
@Override
public Integer value(int slot) {
return fieldValues[slot];
}
}
更新2
文件实体
@Entity
@Table(name = "documents")
@Indexed(index = "documents")
public class EDocument {
public static final String FIELD_NAME = "name";
public static final String FIELD_CREATED = "created";
public static final String FIELD_DESCRIPTION = "description";
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created")
@Field(name = FIELD_CREATED)
private Calendar created;
@Column(name = "name")
@Field(name = FIELD_NAME)
private String name;
@Column(name = "description")
@Field(name = FIELD_DESCRIPTION)
private String description;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
@IndexedEmbedded(depth = 1)
private EUser user;
@OneToMany(
fetch = FetchType.LAZY,
targetEntity = EDownload.class,
mappedBy = "document",
orphanRemoval = true,
cascade = CascadeType.ALL)
@IndexedEmbedded(depth = 1)
private Set<EDownload> downloads;
public EDocument() {
created = Calendar.getInstance();
}
// getters and setters
}
下载实体
@Entity
@Table(name = "downloads")
public class EDownload {
public static final String FIELD_REQUESTED = "requested";
@Id
@GeneratedValue
@Column(name = "id")
private Long id;
@Column(name = "requested")
@Field(name = FIELD_REQUESTED)
private Calendar requested;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "document_id", nullable = false)
private EDocument document;
public EDownload() {
requested = Calendar.getInstance();
}
// getters and setters
}
我可能会使用@IndexedEmbedded
将命中索引为文档索引的@IndexedEmbedded
。 然后,对description
字段运行查询,提供自定义的Sort
实现。 自定义排序将需要数据范围作为参数,然后计算该日期范围内的匹配数并相应地排序。
最后,我进行了类似于@gmansoor建议的操作-第一个查询术语,返回ID,然后第二次基于这些ID查询。 似乎没有办法在Hibernate Search的单个查询中执行此操作,因此,这似乎是目前最好的解决方案。 如果有人知道更好的方法,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.