2017-01-18 6 views
0

を持っている場合、私は複数のクエリを適用し、検索してLucene.netインデックスを持っている:Lucene.netフィルタインデックスレコードが特定の値

BooleanQuery filterQuery = new BooleanQuery(); 

if (searchDto.SubCategoryId != Guid.Empty) 
{ 
    TermQuery tq = new TermQuery(new Term("SubCategoryId", searchDto.SubCategoryId.ToString())); 
    filterQuery.Add(tq, Occur.MUST); 
} 

if (!string.IsNullOrEmpty(searchDto.SearchPhrase)) 
{ 
    var parser = new MultiFieldQueryParser 
     (Version.LUCENE_30, new[] { "Title", "Description", "SubCategoryName", "LongDescription" }, analyzer); 
    var query = parseQuery(searchDto.SearchPhrase, parser); 
    filterQuery.Add(query, Occur.MUST); 
} 

topDocs = searcher.Search(filterQuery, null, hits_limit); 

これは素晴らしい作品。たとえば、サブカテゴリIDを渡すと、サブカテゴリにのみ一致します。しかし、フィルタ値を送信するかどうかではなく、インデックスレコードにそのフィールドの値があるかどうかに基づいて一致するクエリを作成するにはどうすればよいですか。

たとえば、luceneインデックスレコードフィールドの1つはIsBundleです。今、IsBundletrueの場合、RelationshipIdsearchDto.RelationshipIdと一致する場合はレコードを送信します。 IsBundlefalseの場合、私はRelationshipIdを気にしません。だから、私の最終的な結果はIsBundletrueあるレコードとRelationshipIdマッチ私のsearchDto.RelationshipId、あなたはロジックを折りたたむ場合IsBundlefalse

答えて

2

でのいくつかの組み合わせになり、これは

IsBundle==false OR RelationshipID==x 
のちょうど同じではありません

または

var q = new BooleanQuery(); 
q.Add(new TermQuery(new Term("IsBundle", "true"), Occur.SHOULD); 
q.Add(new TermQuery(new Term("RelationshipID", dto.thing), Ocurr.SHOULD); 
1

インデックスフィールドRelationshipIDに関する詳細がなくても、私はRelationshipIDは、文字列の標準であると仮定しますe。 searchDto.RelationshipIDが

IsBundle:false 

このコードはfilterQueryに適切なクエリを追加を与えられていない場合searchDto.RelationshipIDが指定されている場合は

あなたは

(RelationshipID:{searchDto.RelationshipID} AND IsBundle:true) OR IsBundle:false 

をしたいです。

if (!String.IsNullOrEmpty(searchDto.RelationshipID)) 
{ 
    BooleanQuery q = new BooleanQuery(); 
    q.Add(new BooleanClause(
     new TermQuery(new Term("RelationshipId", searchDto.RelationshipID)), Occur.MUST) 
     ); 
    q.Add(new BooleanClause(
     new TermQuery(new Term("IsBundle", "true")), Occur.MUST) 
     ); 
    BooleanClause clause = new BooleanClause(q, Occur.SHOULD); 
    q = new BooleanQuery(); 
    q.Add(clause); 
    q.Add(new BooleanClause(
         new TermQuery(new Term("IsBundle", "false")), Occur.SHOULD) 
         );     
    filterQuery.Add(q,Occur.MUST);    
} 
else 
{ 
    filterQuery.Add(new BooleanClause(
     new TermQuery(new Term("IsBundle", "false")), Occur.MUST) 
     ); 
} 

クエリを組み立てるエレガントな方法がありますが、これは要件を満たしています。