2012-12-17 2 views
8

를 검색하는 사용자가 나는 현재 만들 루씬 3.5 여러 필드를 검색하고 DisjunctionMaxQuery에 검색 할 각 필드에 대한 QueryParser를 추가 할 수 있도록합니다. 기본 연산자로 또는를 사용하지만, 지금보다 정확한 (적은) 결과를 얻을 수 에 기본 연산자를 변경하고자 할 때 잘 작동합니다.루씬 : 여러 개의 기본 연산자 필드 = AND

문제는 모든 용어가이어야 한 필드에 있어야하기 때문에 queryParser.setDefaultOperator(QueryParser.AND_OPERATOR) 미스 많은 문서입니다.

는 예를 들어, 문서에 대한 다음과 같은 데이터를 고려해 제목 필드 = 몸 필드 = "자바, C++, PHP", "프로그래밍 언어". 사용자가 Java 프로그래밍을 검색하는 경우 제목과 본문 필드가 결합되어 있지만 검색어의 모든 용어가 포함되어 있기 때문에이 특정 문서는 결과에 포함되지 않습니다. 이 문서는 위의 쿼리에 대해 반환되지만 쿼리에 대해서는 반환하지 말아야합니다. HTML 프로그래밍.

캐럴 필드를 고려했지만 몇 가지 문제가 있습니다. 첫째, 사용자는 catchall 필드로는 불가능한 쿼리 (작성자 : 계산서)에 필드 당 용어를 자주 포함시킵니다. 또한 FastVectorHighlighter를 사용하여 특정 필드를 강조 표시하고 인덱싱하고 저장해야합니다. 그래서 catchall 필드를 추가함으로써 시간과 공간을 낭비하는 동일한 데이터를 두 번 색인화해야했습니다.

아이디어가 있으십니까?

+0

catchall 필드의 색인 생성과 관련하여 우려할만한 시간/공간 히트를 관찰 했습니까? 내 경험에 의하면 특정 저장된 필드에서 동일한 데이터를 인덱싱 한 다음 일반화 된 인덱스 전용 필드에 추가하면 성능이나 인덱스 크기에 거의 영향을 미치지 않습니다. – femtoRgon

+0

또한 최종 쿼리 구조가 어떻게 생겼는지 궁금합니다. 특히 dis-max 쿼리가 설정되는 방법. 의미있는 점수를 얻기가 쉽습니다. – femtoRgon

+0

@femtoRgon disjunctionMaxQuery 구조체는 다음과 같습니다. '((title : java title : programming) | (body : java body : programming)) ~ 0.2'catchall 필드를 추가하면 먼 시간만큼 영향을 미칠 수 있다는 좋은 지적이 있습니다/space가 관련되어있다. 나는 확실히 그것을 고려했지만 필자와 같은 분야별로 검색 할 수있는 능력을 유지하기를 원한다. 사용자는이 기능을 사용할뿐만 아니라 뒤에서 사용합니다. 고마워. –

답변

6

내가 조금 더 조사 했어야했다. 밝혀졌습니다 MultiFieldQueryParser 정확한 기능을 제공합니다. 내가 무슨하지 않은 ...

(+title:java +title:programming) | (+body:java +body:programming) 

:

String[] fields = {"title", "body", "subject", "author"}; 
QueryParser[] parsers = new QueryParser[fields.length];  
for(int i = 0; i < parsers.length; i++) 
{ 
    parsers[i] = new QueryParser(Version.LUCENE_35, fields[i], analyzer); 
    parsers[i].setDefaultOperator(QueryParser.AND_OPERATOR); 
} 

이이 같은 쿼리가 발생할 것이다 : 나는 각 필드에 대한 QueryParser를 생성 한 어떤 이유를 들어 나는이 같은 검색 원 찾고. 지금은 이런 식으로 하나의 MultiFieldQueryParser을 만듭니다

MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_35, new String[]{"title", "body", "subject"}, analyzer); 
parser.setDefaultOperator(QueryParser.AND_OPERATOR); 

이 나에게 내가 찾던 쿼리를 제공합니다 도움을 @seeta 및 @femtoRgon에

+(title:java body:java) +(title:programming body:programming) 

감사합니다!

2

아마도 필요한 것은 필드와 용어의 다양한 조합을 캡처하는 부울 쿼리의 조합 일 것입니다. 당신의 주어진 예에서, 쿼리가 될 수있다 -

(제목 : 자바와 신체 프로그래밍) 또는 (제목 : 프로그래밍 및 신체 : 자바).

당신을 위해이 작업을 자동으로 생성하는 기존의 쿼리 클래스가 있는지 잘 모르겠지만, 난 그 인덱스에서 실행있어 궁극적 인 쿼리해야 무슨 생각합니다.

+0

당신이 올바른 길을 가고 있다고 생각하지만 AND와 OR이 바뀌는 것이 더 좋을 것이라고 생각하십니까? (제목 : 자바 OR 본문 : 자바 OR 제목 : 자바) AND (제목 : 프로그래밍 OR 본문 : 프로그래밍 또는 주제 : 프로그래밍) ... [추가 용어 처리] ... 나는 다른 사람들을 위해 완료되면 내 구현을 게시 할 것입니다 가능한 해결책. 대답은 Thx입니다. –

0

당신은 당신의 코멘트에서 다음 용어의 동일한 세트로 질문을 여러 필드를 검색 할 수있는 :

((title:java title:programming) | (body:java body:programming))~0.2 

최고의 구현되지 않을 수 있습니다.

제목에서 점수를 얻거나 조합 된 단어 집합의 본문에서 점수를 얻는 것이 효과적입니다. 제목에서 Java를 누르고 본체에서 프로그래밍하는 경우는 대략 주어집니다. 본문에서 자바에 대한 히트와 같은 가중치와 프로그래밍에 대한 히트가 없습니다.

내가 더 잘 구조화 된 쿼리가있을 거라고 생각 :

(title:java body:java)~0.2 (title:programming body:programming)~0.2 

이것은 나에게 더 의미가 당신이 dismax 쿼리 (다른 분야에서) 같은 용어의 여러 쿼리에 성장 점수를 제한 할 수 있기 때문에, 그러나 당신은 다른 기간에 명중을 위해 성장하기 위하여 득점을 원한다, 나는 믿는다.

이러한 쿼리 구조를 사용하면 점수 결과가 좋아지고 결과가 너무 약한 결과를 방지하기 위해 결과를 특정 최소 점수 (단순한 하드 코드 값이 아닌 반환 된 최대 점수의 백분율)로 제한하는 것이 적합 할 수 있습니다 보지 못했다.


는 또한 여전히 모든 필드 색인 세지 않을 것이다. 특정 필드와 catchall 필드 모두를 인덱싱하는 동안 이전에 사용한 구현이므로 일반 쿼리와 특정 단일 필드 쿼리를 모두 허용합니다. 인덱스 저장은 저장되지 않은 용어에 대해 꽤 간결한 경향이 있으며 일반적으로 성능이 좋지 않은 경우를 보충하기 위해 크고 복잡한 쿼리를 작성해야하는 경우 일반적으로 성능에 도움이됩니다.

new Field(name, value, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.NO); 

정말 만들 수있는 차이의 정도를 알 수 없지만 :

당신이 정말로 그것을 최소한의 스토리지 소요, 당신도 그 분야에 대한 TermVectors을 해제 할 수 있는지 확인하는 것이 좋습니다 경우

.