2011-10-17 1 views
0

사용자가 검색 상자에 구문을 입력하면 (따옴표 사용 여부와 상관없이) 문서 제목에 정확한 문구가 표시되고 그 후에 표시되는 기타 문서가 있어야합니다. 인덱싱 동안제목 필드와 QueryParser에 대한 PhraseQuery가 catch 필드에 대해 예상 한 결과를 얻지 못합니다.

내가 말 :

AddStringFieldToDocument(document, "keyWord", this.BuildKeywordsString(), Field.Store.NO, Field.Index.ANALYZED, false); 

AddStringFieldToDocument(document, "title", this.Title, Field.Store.NO, Field.Index.ANALYZED, false, 4f); 

    private void AddStringFieldToDocument(Document document, string fieldName, string fieldValue, 
     Field.Store store, Field.Index index, bool setOmitTermFreqAndPositions) 
    { 
     if (fieldValue == null) 
     { 
      return; 
     } 
     var field = GetFieldToAddToDocument(document, fieldName, fieldValue, store, index, setOmitTermFreqAndPositions); 
     document.Add(field); 
    } 

    private void AddStringFieldToDocument(Document document, string fieldName, string fieldValue, 
     Field.Store store, Field.Index index, bool setOmitTermFreqAndPositions, Single boost) 
    { 
     if (fieldValue == null) 
     { 
      return; 
     } 

     var field = GetFieldToAddToDocument(document, fieldName, fieldValue, store, index, setOmitTermFreqAndPositions); 
     field.SetBoost(boost); //boosting title 
     document.Add(field); 
    } 

    private Field GetFieldToAddToDocument(Document document, string fieldName, string fieldValue, Field.Store store, 
     Field.Index index, bool setOmitTermFreqAndPositions) 
    { 
     Field field = new Field(fieldName, fieldValue, store, index); 
     field.SetOmitTermFreqAndPositions(setOmitTermFreqAndPositions); 
     return field; 
    } 

검색시 내 BooleanQuery의 일부로서 내가 가진 :

if (!string.IsNullOrWhiteSpace(queryString)) 
     { 
      QueryParser qpKeyWord = new QueryParser(myVersionUsed, "keyWord", StandardAnalyzer); 

      Query qKeyWord = qpKeyWord.Parse(queryString); 
      booleanQuery.Add(qKeyWord, BooleanClause.Occur.MUST); 

      Term titleTerm = new Term("title", queryString); 
      PhraseQuery qTitleWord = new PhraseQuery(); 
      qTitleWord.SetSlop(12); 
      qTitleWord.Add(titleTerm); 
      qTitleWord.SetBoost(5); 
      booleanQuery.Add(qTitleWord, BooleanClause.Occur.SHOULD); 
이 내가 시도하지만 그 순서대로 검색 결과를 나에게 제공하지 것입니다

나는 결과가 섞여있다. 내가 IndexSearcher.Explain (쿼리, DOCID)

을 실행할 때 또한, 내가 얻을 다음 PhraseQuery와 연관된 번호가 없지만, 각 키워드에 대해 별도의 번호를 가지고

Document Id: 92871 
0.5439626 = (MATCH) product of: 
    0.8159439 = (MATCH) sum of: 
    0.5884751 = (MATCH) sum of: 
     0.2580064 = (MATCH) weight(KeyWord:chicken in 92871), product of: 
     0.2226703 = queryWeight(KeyWord:chicken), product of: 
      3.236447 = idf(docFreq=25345, maxDocs=237239) 
      0.06880084 = queryNorm 
     1.158692 = (MATCH) fieldWeight(KeyWord:chicken in 92871), product of: 
      4.582576 = tf(termFreq(KeyWord:chicken)=21) 
      3.236447 = idf(docFreq=25345, maxDocs=237239) 
      0.078125 = fieldNorm(field=KeyWord, doc=92871) 
     0.3304687 = (MATCH) weight(KeyWord:parmesan in 92871), product of: 
     0.2962231 = queryWeight(KeyWord:parmesan), product of: 
      4.305515 = idf(docFreq=8701, maxDocs=237239) 
      0.06880084 = queryNorm 
     1.115608 = (MATCH) fieldWeight(KeyWord:parmesan in 92871), product of: 
      3.316625 = tf(termFreq(KeyWord:parmesan)=11) 
      4.305515 = idf(docFreq=8701, maxDocs=237239) 
      0.078125 = fieldNorm(field=KeyWord, doc=92871) 
    0.2274688 = (MATCH) weight(has_photo:y in 92871), product of: 
     0.1251001 = queryWeight(has_photo:y), product of: 
     1.818294 = idf(docFreq=104665, maxDocs=237239) 
     0.06880084 = queryNorm 
     1.818294 = (MATCH) fieldWeight(has_photo:y in 92871), product of: 
     1 = tf(termFreq(has_photo:y)=1) 
     1.818294 = idf(docFreq=104665, maxDocs=237239) 
     1 = fieldNorm(field=has_photo, doc=92871) 
    0.6666667 = coord(2/3) 

합니다. 그러나 검색시
나는 내가 얻을() query.ToString를 실행하면

쿼리를 잘 작성되었음을 의미
+(KeyWord:chicken KeyWord:parmesan) title:"Chicken Parmesan"~12^5.0 

. 권리? 내가 뭘 놓치고 있니?

답변

2

당신이 제목에 대한 쿼리를 작성하는 방법 나는 당신이 title 절에서 시작된 히트를 결코 얻지 못할 것으로 생각합니다.

"치킨 파르 메산 치즈"라는 단 어를 찾기 위해 PhraseQuery를 만들었지 만 색인 생성시 StandardAnalyzer는 "닭고기"와 "파르 메산 치즈"라는 두 가지 용어를 만들어 냈습니다. 이 두 가지 용어로 PhraseQuery를 구축해야합니다.

이 목적을 위해 QueryParser을 사용할 수 있습니다 : 당신이 QueryParser를 사용하려는 해달라고하면

QueryParser qp = new QueryParser("keyWord", new StandardAnalyzer()); 
    Query q = qp.Parse("+(keyWord:chicken KeyWord:parmesan) title:\"Chicken Parmesan\"~12^5.0"); 
    var hits = searcher.Search(q); 

, 토큰에 텍스트를 중단 할 수 TokenStream API를 사용

PhraseQuery titleQuery = new PhraseQuery(); 
    titleQuery.SetSlop(12); 
    titleQuery.SetBoost(5); 
    BooleanQuery keywordQuery = new BooleanQuery(); 

    var standard = new StandardAnalyzer(); 
    TokenStream tokens = standard.TokenStream("title", new StringReader("Chicken Parmesan")); 
    List<Term> terms = new List<Term>(); 
    while (tokens.IncrementToken()) 
    { 
     TermAttribute termAttribute = (TermAttribute)tokens.GetAttribute(typeof(TermAttribute)); 

     titleQuery.Add(new Term("title", termAttribute.Term())); 

     keywordQuery.Add(
      new TermQuery(
       new Term("keyWord", termAttribute.Term())), 
      BooleanClause.Occur.SHOULD); 
    } 

    BooleanQuery query = new BooleanQuery(); 
    query.Add(keywordQuery, BooleanClause.Occur.MUST); 
    query.Add(titleQuery, BooleanClause.Occur.SHOULD); 

    var hits = searcher.Search(query); 
+0

감사합니다! 당신의 대답은 매력처럼 일했습니다 :) – Barka

관련 문제