2009-10-12 1 views
5

"유형"필드가있는 문서를 포함하는 Lucene 인덱스가 있는데이 필드는 "article", "forum"또는 " 블로그 ". 사용자가 이러한 유형 내에서 검색 할 수 있기를 원합니다. 각 문서 유형에 대한 확인란이 있습니다.Lucene 쿼리 - "x, y, z 중 정확히 일치"

사용자가 선택한 유형에 따라 Lucene 쿼리를 만드는 방법은 무엇입니까?

는 전제 조건의 몇 가지 있습니다 : 사용자가 유형 중 하나를 선택하지 않습니다

  • 경우에, 나는 그 유형에서 결과를 원하는 없습니다.
  • 형식 필드를 제한하면 결과의 순서가 영향을받지 않습니다. 나는 SQL이 작성한다면 참고로

(대한 "블로그 또는 포럼 검색") 내가 쓰는 것 :

SELECT * FROM Docs 
WHERE [type] in ('blog', 'forum') 

답변

4

가, 다른 사람이이 문제를 가로 질러 와야한다, 여기 내 솔루션입니다 결과의 순서가 유실됩니다. 왜 그래도 ...! 그것은 코드를 덜 명확하게/유지 보수 할 수있게 해줄만큼 수치 스럽지만 적어도 작동합니다!

3

가 선택되지 않은 문서를 거부하는 제약 조건을 추가합니다. 전용 "문서는"확인 된 경우 예를 들어, 제약 될

-(type:forum type:blog) 
+0

이것은 결국 내가 한 일입니다. API를 문자열로 작성하는 대신 사용했지만 관심이 있다면 제 대답을 참조하십시오. – thatismatt

0

에릭슨의 제안은 잘 보이지만, 당신은 경우에만 "기사"에 대한 text:foo AND type:article 등의 검색어로 AND 연산 긍정적 인 제약 조건을 사용할 수 있습니다 'article'과 'forum'이 모두 확인 된 경우 또는 text:foo AND (type:article OR type:forum)을 확인했습니다. 당신이하지 않을 경우 때문에이 논리를 반전

IList<string> ALL_TYPES = new[] { "article", "blog", "forum" }; 
string q = ...; // The user's search string 
IList<string> includeTypes = ...; // List of types to include 
Query searchQuery = parser.Parse(q); 
Query parentQuery = new BooleanQuery(); 
parentQuery.Add(searchQuery, BooleanClause.Occur.SHOULD); 
// Invert the logic, exclude the other types 
foreach (var type in ALL_TYPES.Except(includeTypes)) 
{ 
    query.Add(
     new TermQuery(new Term("type", type)), 
     BooleanClause.Occur.MUST_NOT 
    ); 
} 
searchQuery = parentQuery; 

가 (즉, 사용자가 선택하지 않은 유형을 제외) : 참고로

+0

흥미롭게도 두 개의 쿼리 "text : foo AND (type : article OR type : forum)"및 "text : foo AND-type : blog"는 동일한 결과를 제공하지 않지만 첫 번째 쿼리는 블로그를 먼저 반환하고 두 번째 쿼리는 질의는 주문 (즉, 블로그와 기사가 섞여 있음)을 유지합니다. 왜 그런가? – thatismatt

+0

Lucene에는 "AND"연산자가 없습니다. 그것은 + (요구)와 - (금지) 운영자를가집니다. – erickson

+0

@erickson : 나는 다르다 : 예. http://incubator.apache.org/lucene.net/docs/2.1/Lucene.Net.QueryParsers.QueryParser.AND_OPERATOR.html –