これを行う 1 つの方法は、カスタム フィルターを使用することです。たとえば、ドメイン クラスの 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;
}
}
次に、フィルターを検索の引数として配置します (別のパッケージにある場合は、Filter クラスをインポートするようにしてください)。
def theSearchResult = MyDomainClass.search(
{
must( queryString(params.q) )
},
params,
filter: new IdFilter( [ "1" ] ))
ここでは、"1" という単一の値を含むハードコードされたリストを作成しているだけですが、データベースから、以前の検索から、またはどこからでも ID のリストを取得できます。
コンストラクターで用語名を取得し、必要に応じて「名前」を渡す必要があるフィルターを簡単に抽象化できます。