2010-01-13 7 views
8

어떻게 Lucene.NET에서 "OR"을 수행합니까? 기본적으로 ID의 배열이며 특정 필드에 값이 들어있는 레코드를 반환하려고합니다. 이전에 단 하나의 값으로이 작업을 수행했지만 지금은 MetaDataID가 단일 값 대신 가능한 값의 배열이되도록 다음 코드를 변환하려고합니다. 이 최대 부울 조항의 제한이 있기 때문에Lucene.NET "OR"

if (MetaDataID.Length > 0) 
    completeQuery.Add(new QueryParser("MetaData", new StandardAnalyzer()).Parse(MetaDataID), BooleanClause.Occur.MUST); 

답변

4

당신은, ID로 문서를 검색하는 BooleanQuery를 사용할 때주의 대신 BooleanClause.Occur.MUST

예컨대 :

BooleanQuery booleanQuery = new BooleanQuery(); 
Query query1 = new TermQuery(new Term("id", "<id 1>")); 
Query query2 = new TermQuery(new Term("id", "<id 2>")); 
booleanQuery.add(query1, BooleanClause.Occur.SHOULD); 
booleanQuery.add(query2, BooleanClause.Occur.SHOULD); 
+0

이것은 A | B 집합을 반환하지 않는 것처럼 보입니다. 이것을 시도 할 때 다른 MUST 절과 일치하는 모든 레코드를 얻고 있습니다. 즉 SHOULD가 무시되고있는 것처럼 보입니다. – Kyle

+1

잘 모르겠습니다. 하지만 당신이해야 할 일은 BooleanQuery를 중첩하는 것입니다. –

+0

'네가 쓸데없이 ... 필요해.'-하지만 왜? –

2

BooleanClause.Occur.SHOULD를 사용해야합니다.

기본 "OR"루씬에 절은 검색 필드가 "ID"라는 가정, 다음과 같이 수행됩니다

"ID : 1 ID : 2 ID : 3 ID : 4"

"+ ID : 1 + ID : 2 + ID : 3 + ID : 4"

당신을 위해 마법을해야 할 표준 QueryParser과의 StringBuilder를 사용하는 대신 "AND"쿼리.

3

쿼리를 구문 분석하려면 쿼리에 대해 올바른 분석기 및 형식을 선택하기 만하면됩니다.

StandardAnalyzer는 영어 전체 텍스트를 인덱싱 할 때 좋은 선택이 아닙니다. 특히 귀하의 경우는 아닙니다! 그것은 숫자를 걸러냅니다!

가장 짧은 해결책은 분리 기호를 토큰 화하고 해당 개체를 문자열로 결합하는 분석기를 만드는 것입니다.

예 :

만들기 전형적인 seperators에서 분할 토크 나이와 파서

을에서에게

using System.IO; 
using System.Linq; 
using Lucene.Net.Analysis; 

namespace Project.Analysis 
{ 
    public class TermTokenizer : LetterTokenizer 
    { 
     // some static separators 
     private static readonly char[] NONTOKEN_CHARS = new char[] { ',', ';', ' ', '\n', '\t' }; 

     protected override bool IsTokenChar(char c) 
     { 
      return !NONTOKEN_CHARS .Contains(c); 
     } 
    } 

    public class LowerCaseTermAnalyzer : Analyzer 
    { 
     public override TokenStream TokenStream(string fieldName, TextReader reader) 
     { 
      return new LowerCaseFilter(new TermTokenizer(reader)); 
     } 
    } 
} 

를 사용하여 새로운 분석기를 사용하는 분석기 (당신 System.Linq 포함)

if (MetaDataID.Length > 0) 
{ 
    // the search term will look like this: "1;5;7" 
    string searchTerm = string.Join(";", MetaDataID); 

    // the query parser uses the new Analyzer 
    QueryParser parser = new QueryParser("MetaData",new LowerCaseTermAnalyzer()); 

    // the parsed search term (only used internally) will look like this: 
    // "MetaData:1 MetaData:5 MetaData:7", which is essentially what you want to achieve 
    completeQuery.Add(new parser.Parse(MetaDataID), BooleanClause.Occur.MUST); 
} 
10

여러 개의 가능한 값 중 하나를 포함하는 인덱스 레코드와 일치해야하는 추가 기준이 필요한 곳에서 Lucene 쿼리를 결합 할 때 여러 개의 부울 쿼리 개체를 만듭니다."OR"조건의 첫 번째 그룹에 대해

:

BooleanQuery booleanQueryInner = new BooleanQuery(); 
Query query1 = new TermQuery(new Term("id", "<id 1>")); 
Query query2 = new TermQuery(new Term("id", "<id 2>")); 
Query query3 = new TermQuery(new Term("id", "<id 3>")); 
Query query4 = new TermQuery(new Term("id", "<id 4>")); 
booleanQueryInner.add(query1, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query2, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query3, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query4, BooleanClause.Occur.SHOULD); 

지금 쿼리에 다른 조건과 결합

BooleanQuery booleanQueryOuter = new BooleanQuery(); 
booleanQueryOuter.add(booleanQueryInner, BooleanClause.Occur.MUST); 
booleanQueryOuter.add(boolenaQueryOtherConditions, BooleanClause.Occur.MUST); 

그들 중 하나 충족하는 경우 이제 인덱스 레코드 만 반환됩니다 내부 "OR"그룹의 조건과 "기타 조건"쿼리의 조건을 충족해야합니다.