一种方法是使用自定义过滤器。例如,如果您想根据域类的 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 列表。
您可以轻松地抽象过滤器,我必须在构造函数中获取术语名称,然后像您想要的那样传入“名称”。