gpt4 book ai didi

grails - 使用Compass/Lucene搜索对象的子集

转载 作者:行者123 更新时间:2023-12-02 14:16:03 24 4
gpt4 key购买 nike

我正在使用Grails的可搜索插件(该插件提供了Compass的API,它本身就是Lucene上的API)。我有一个想搜索的Order类,但是我不想搜索Order的所有实例,而只是它们的一个子集。像这样:

// This is a Hibernate/GORM call
List<Order> searchableOrders = Customer.findAllByName("Bob").orders

// Now search only these orders with the searchable plugin - something like
searchableOrders.search("name: foo")

实际上,获取searchableOrders的关系查询要比这复杂得多,因此我不能仅靠指南针来完成整个查询(休眠+指南针)。有没有一种方法可以使用Compass / Lucene仅搜索特定类的实例的主题。

最佳答案

一种方法是使用自定义过滤器。例如,如果要基于域类的ID进行过滤,则可以将ID添加到域类的可搜索配置中:

static searchable = {
id name: "id"
}

然后,您将编写自定义过滤器(可以在[project] / src / java中使用):
import org.apache.lucene.search.Filter;
import java.util.BitSet;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;

import java.io.IOException;
import java.util.List;

public class IdFilter extends Filter {

private List<String> ids;

public IdFilter(List<String> ids) {
this.ids = ids;
}

public BitSet bits(IndexReader reader) throws IOException {
BitSet bits = new BitSet(reader.maxDoc());
int[] docs = new int[1];
int[] freqs = new int[1];
for( String id : ids ) {
if (id != null) {
TermDocs termDocs = reader.termDocs(new Term("id", id ) );
int count = termDocs.read(docs, freqs);
if (count == 1) {
bits.set(docs[0]);
}
}
}
return bits;
}
}

然后,将过滤器作为搜索的参数(如果将过滤器类放入其他包中,请确保将其导入):
def theSearchResult = MyDomainClass.search( 
{
must( queryString(params.q) )
},
params,
filter: new IdFilter( [ "1" ] ))

在这里,我只是创建一个硬编码列表,其中包含单个值“1”,但是您可以从数据库,先前的搜索或任何地方检索ID列表。

您可以轻松地抽象出过滤器,我必须在构造函数中使用术语名称,然后根据需要传入“名称”。

关于grails - 使用Compass/Lucene搜索对象的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1808920/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com