2014-10-22 8 views
0

색인에있는 각 항목의 필드는 TYPE입니다. 이 중 하나를 "Document", "Blog" or "Forum"Lucene OR에 해당하는 중첩 부울

사용자들이 검색 할 TYPE의 선택할 수 수 있지만, "문서"를 검색 할 경우, 나는 그것의 STARTDATE 필드가 떨어질 경우 유효한에 "Document" 유형 만 반환되도록하는 범위 쿼리를 추가 할 필요가있다

{+ (유형 : 문서 + STARTDATE : [*가 20141022000000] 종류 : 블로그 게시물 유형 : ForumQuestion 유형 : ForumIdea 유형 : ForumIdeaList 유형 : ForumDiscussion)}

범위

using (var searcher = new IndexSearcher(_directory, false)) 
     { 

    var analyzer = new StandardAnalyzer(Version.LUCENE_29); 

    BooleanQuery booleanQuery = new BooleanQuery(); 
    BooleanQuery innerTypeFilterQuery = new BooleanQuery(); 

    long today = Convert.ToInt64(LuceneDate.Today().Value); 

    foreach (string filterItem in filterItems) 
    { 
     TermQuery filterItemQuery = new TermQuery(new Term("Type", filterItem)); 
     innerTypeFilterQuery.Add(filterItemQuery, Occur.SHOULD); 

     if (filterItem == "Document") 
     { 
     innerTypeFilterQuery.Add(NumericRangeQuery.NewLongRange("StartDate", null, today, true, true), Occur.MUST); 
     } 
    } 

    if (innerTypeFilterQuery.Clauses.Count > 0) 
    { 
     booleanQuery.Add(innerTypeFilterQuery, Occur.MUST); 
    } 

    Sort sort = new Sort(new SortField(LuceneGeneric.IndexFields.StartDate, Lucene.Net.Search.SortField.LONG, true)); 
    var hits = searcher.Search(booleanQuery, null, LuceneContentWidgetResult.HITS_LIMIT, sort).ScoreDocs; 
    var results = _mapLuceneContentWidgetSearchResultsToDataList(hits, searcher); 
    analyzer.Close(); 
    searcher.Dispose(); 
    return results; 
} 

내 쿼리는 다음과 같습니다

답변

1

그것은 당신이 달성하기를 원하는 것에 달려 있습니다.

의 당신이 문서에 있다고 가정 해 봅시다 :

title=foo 
date=100 // using numeric value for simplicity 

여기 쿼리의 두 가지 유형에 대한 진리표 (모두 단일 BooleanQuery으로 수행)

query      | doc match result 
------------------------------------------------------------------------------------- 
title:foo +date:[80 TO 150] | true (both matched) 
title:foo +date:[10 TO 20] | false (date hasn't matched even though title matched) 
title:boo +date:[80 TO 150] | true (date matched but title hasn't) 
title:boo +date:[10 TO 20] | false (none matched) 
------------------------------------------------------------------------------------- 
title:foo date:[80 TO 150] | true (both matched) 
title:foo date:[10 TO 20]  | true (date hasn't matched but title matched) 
title:boo date:[80 TO 150] | true (date matched but title hasn't) 
title:boo date:[10 TO 20]  | false (none matched) 

당신이 볼 수 있듯이의를, 날짜 MUST입니다 처음 4 테이블 행은 SHOULD이고, 하단 4 행은 SHOULD입니다.

Q는> 추가하는 방법 확실하지 임, 전,> 다시 innerTypeFilterQuery
A를 다른 부울 쿼리를 추가 당신이 원하는 결과를 일치하는 어떤 종류의 설명 만하시기 바랍니다해야합니까 위의 사실 테이블에서 어떤 결과가 당신의 요구 사항을 만족하는 경우, 동일한 쿼리에 추가 할 수 있습니다.

편집 : 나는 당신의 질문이 아니라 같이해야한다고 생각 :

+((Type:Document +StartDate:[* TO 20141022000000]) Type:BlogPost Type:ForumQuestion Type:ForumIdea Type:ForumIdeaList Type:ForumDiscussion) 

그래서 그래, 당신이 두 문서의 제약을 포장하기 위해 별도의 부울 쿼리가 필요합니다.

+0

Thankyou - 내가 좋아하는 예제를 사용하면 제목 = "foo"를 검색 할 때 범위 검색을 추가하고 싶습니다. 이 경우 Foo는 거기에있을 것임을 알 수있는 상수입니다. 다른 검색에는 범위가 포함되지 않습니다. 기본적으로 문서는 만료 날짜가 있으므로 생략하고 싶습니다. – DavidB

+0

질문을 * 완전한 * 진실 표로 바꿀 수 있습니까? 지금 나는 당신이 달성하고자하는 것을 이해하지 못합니다. – mindas

+0

죄송합니다. 진리 테이블에 대한 경험이 없으므로 충분한 편집을하시기 바랍니다. – DavidB