Lucene.netを使用して商品カタログのインデックスを作成しています。私はANTS Profilerを使用して検索をプロファイリングしていましたが、MultiFieldQueryParserを使用してクエリを作成および解析する行為は、実際の検索(約100ms)とほぼ同じくらい長くかかることに気付きました。私はその後、手動でクエリを作成しようとしましたが、これは非常に高速です(約1ms)。手動で解析する必要はありませんが、結果セットは同じですが、特定のユースケースや入力を処理していない可能性があります(ただし、入力はウェブサイトのテキスト検索から来ていますが、ユーザーはわかりませんLuceneの検索構文に関するもの)。以下のように(両方の方法で)私のコードは次のとおりです。MultiFieldQueryParserは手作業でクエリを作成するよりもずっと遅いのはなぜですか?
IApplicationSettings settings = new ApplicationSettingService();
FSDirectory directory = FSDirectory.Open(new DirectoryInfo(settings.GetSetting<string>("LuceneMainSearchDirectory")));
RAMDirectory ramDir = new RAMDirectory(directory);
_Searcher = new IndexSearcher(ramDir, true);
string[] searchFields = new string[] { "ProductName", "ProductLongDescription", "BrandName", "CategoryName" };
//Add a wildcard character to end of search to give broader results
if (!searchTerm.EndsWith(" ")) { searchTerm = searchTerm + "*"; }
//Use query parser...this block typically takes about 100ms on my machine, roughly 40% on the constructor and 60% on the call to Parse
MultiFieldQueryParser multiParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, searchFields, _analyzer);
multiParser.SetDefaultOperator(QueryParser.AND_OPERATOR);
Query query = multiParser.Parse(searchTerm);
//Manually create query....this block doesn't even take 1ms on my machine
BooleanQuery booleanQuery = new BooleanQuery(true);
var terms = searchTerm.Split(' ');
foreach (string s in terms)
{
BooleanQuery subQuery = new BooleanQuery(true);
if (!s.EndsWith("*"))
{
Query query1 = new TermQuery(new Term("ProductName", s));
Query query2 = new TermQuery(new Term("ProductLongDescription", s));
Query query3 = new TermQuery(new Term("BrandName", s));
Query query4 = new TermQuery(new Term("CategoryName", s));
subQuery.Add(query1, BooleanClause.Occur.SHOULD);
subQuery.Add(query2, BooleanClause.Occur.SHOULD);
subQuery.Add(query3, BooleanClause.Occur.SHOULD);
subQuery.Add(query4, BooleanClause.Occur.SHOULD);
}
else
{
Query query1 = new WildcardQuery(new Term("ProductName", s));
Query query2 = new WildcardQuery(new Term("ProductLongDescription", s));
Query query3 = new WildcardQuery(new Term("BrandName", s));
Query query4 = new WildcardQuery(new Term("CategoryName", s));
subQuery.Add(query1, BooleanClause.Occur.SHOULD);
subQuery.Add(query2, BooleanClause.Occur.SHOULD);
subQuery.Add(query3, BooleanClause.Occur.SHOULD);
subQuery.Add(query4, BooleanClause.Occur.SHOULD);
}
booleanQuery.Add(subQuery, BooleanClause.Occur.MUST);
}
//Run the search....results are the same for simple multiword text queries
var result2 = _Searcher.Search(booleanQuery, null, maxResults);
var result = _Searcher.Search(query, null, maxResults);
一つの選択肢はMultiFieldQueryParserを共有するかもしれない手動クエリーのビルドを使用して、私を救うために、私は唯一のことを読むが、私は(そのParseメソッドは、スレッドセーフではありません集まりますjavaバージョンとの関係で...私がその仮定で間違っている場合は私を修正してください)。
私は何か間違っているのですか?これは獣の本質ですか?