As usual I turn to the massive brain power that is the Stackoverflow user base to help solve a Lucene.NET problem I am battling with. First off, I am a complete noob when it comes to Lucene and Lucene.NET and by using the scattered tutorials and code snippets online, I have cobbled together the follow solution for my scenario.
The Scenario
I have an index of the following structure:
---------------------------------------------------------
| id | date | security | text |
---------------------------------------------------------
| 1 | 2011-01-01 | -1-12-4- | some analyzed text here |
---------------------------------------------------------
| 2 | 2011-01-01 | -11-3- | some analyzed text here |
---------------------------------------------------------
| 3 | 2011-01-01 | -1- | some analyzed text here |
---------------------------------------------------------
I need to be able to query the text field, but restrict the results to users that have specific roleId's.
What I came up with to accomplish this (after many, many trips to Google) is to use a "security field" and a Lucene filter to restrict the result set as outlined below:
class SecurityFilter : Lucene.Net.Search.Filter
{
public override System.Collections.BitArray Bits(Lucene.Net.Index.IndexReader indexReader)
{
BitArray bitarray = new BitArray(indexReader.MaxDoc());
for (int i = 0; i < bitarray.Length; i++)
{
if (indexReader.Document(i).Get("security").Contains("-1-"))
{
bitarray.Set(i, true);
}
}
return bitarray;
}
}
... and then ...
Lucene.Net.Search.Sort sort = new Lucene.Net.Search.Sort(new Lucene.Net.Search.SortField("date", true));
Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
Lucene.Net.Search.IndexSearcher searcher = new Lucene.Net.Search.IndexSearcher(Lucene.Net.Store.FSDirectory.Open(indexDirectory), true);
Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "text", analyzer);
Lucene.Net.Search.Query query = parser.Parse("some search phrase");
SecurityFilter filter = new SecurityFilter();
Lucene.Net.Search.Hits hits = searcher.Search(query, filter, sort);
This works as expected and would only return documents with the id's of 1 and 3. The problem is that on large indexes this process becomes very slow.
Finally, my question... Does anyone out there have any tips on how to speed it up, or have an alternate solution that would be more efficient than the one I have presented here?