2013-04-18 1 views
4

, 실패 은 "접시"를 포함해야하며 "xyz"는 포함하지 않아야합니다 (). 그것은 실패하고있는 "해야만하는"부분입니다. 루씬 쿼리 필드라는 이름의 내용에 색인이 텍스트 문서를 감안할 때 혼합 MUST/MUST_NOT

나는 + 알 - 특히 고려, 조합이 재미 보이지만 구문이 정확해야 그 다음 변화 모든 작업 :

+Content:dish +(-Content:xyz +Content:spoon) <-- this works 
+Content:dish -Content:xyz      <-- this works 

+(-Content:xyz) 작업을 수행하지? 디자인에 의한 것입니까, 아니면 버그입니까, 아니면 그냥 놓친 것입니까? 나는 Lucene.Net을 사용하고 있지만 Lucene은 규칙적으로 동작한다고 가정합니다.

답변

9

Lucene은 SQL 데이터베이스와 같은 모든 것을 전체적으로 볼 수 없습니다. Lucene은 일치하는 문서가 없으면 시작하고 검색된 절을 기반으로 항목을 찾습니다. 이는 다음과 같은 이유 때문입니다.

-Content:xyz 

실제로는 작동하지 않습니다. 그것은 콘텐츠를 가져 오지 않는 것을 알고 있습니다 : xyz, 그러나 일치시킬 문서를받지 못했습니다. 하위 쿼리에 포함되어 있기 때문에 쿼리에 대해서도 마찬가지입니다.

-Content:xyz이 먼저 평가되며, 문서는 소유하고 있지 않습니다. 그럼 당신은

+Content:dish +(no documents) 

효과적으로 가지고 그것은 AND NOT- 생각하기보다는 단순히이 NOT (비록 암시하는 +/-와 AND/OR/매핑 반드시 구문하지 않음이 적용되지 않습니다 유용 서로 직접).

그런 외로운 부정적인 쿼리를 실행하려면 먼저 모든 문서를 가져와야합니다.

BooleanQuery query = new BooleanQuery(); 
query.add(new BooleanClause(new MatchAllDocsQuery(), BooleanClause.Occur.SHOULD)); 
query.add(new BooleanClause(new TermQuery(new Term("Content","xyz")), BooleanClause.Occur.MUST_NOT)); 

는 WHERE 절에 대해서만 부정으로 SQL 스타일의 쿼리에 해당겠습니까 다음 MatchAllDocsQuery는 작업을 수행하는 가장 좋은 방법은, 같은 것입니다.

+Content:dish -Content:xyz 

완벽하게 적절한인가 : 물론

,이 때문에 당신은 나와 한 경우에 정말 필요가 없습니다.

+0

지금 나에게 의미가 있습니다. 감사! – Keith

+0

FYI MatchAllDocsQuery의 문자열 표현은'* : *'입니다. 위 예제는 다음과 같이 변경되어야합니다 :'+ Content : dish + (+ * : * - 컨텍스트 : xyz)' – Keith

+1

@Keith 음, 아니요, ** ** 변경해야합니다 : '내용 : 요리 - 정숙 : xyz', 그러나 그렇다, 그것은 (천천히) 일할 것이다. '* : * '에 대한 지원이 (솔라에서 지원되는지, 어떤 버전에서 지원되는지, .Net impl에 의해 지원되는지에 상관없이) 어떤 것이 었는지 상기 할 수 없습니다. – femtoRgon