#include "CLucene/StdHeader.h" #include "PhraseQuery.h" #include "SearchHeader.h" #include "Scorer.h" #include "BooleanQuery.h" #include "TermQuery.h" #include "CLucene/index/Term.h" #include "CLucene/index/Terms.h" #include "CLucene/index/IndexReader.h" #include "CLucene/util/StringBuffer.h" #include "CLucene/util/VoidList.h" #include "ExactPhraseScorer.h" #include "SloppyPhraseScorer.h" using namespace lucene::index; using namespace lucene::util; namespace lucene{ namespace search{ PhraseQuery::PhraseQuery(): idf(0.0f), weight(0.0f), slop(0) { } PhraseQuery::~PhraseQuery(){ for (int i=0;ifinalize(); } const char_t* PhraseQuery::getQueryName() const{ return _T("PhraseQuery"); } void PhraseQuery::add(Term* term) { if (terms.size() == 0) field = term->Field(); else if ( stringCompare(term->Field(), field) != 0){ char_t buf[180]; stringPrintF(_T("All phrase terms must be in the same field: %s"),term->Field()); _THROWX(buf); } terms.push_back(term->pointer()); } float_t PhraseQuery::sumOfSquaredWeights(Searcher& searcher) { for (uint_t i = 0; i < terms.size(); i++) // sum term IDFs idf += Similarity::idf(*terms.at(i), searcher); weight = idf * boost; return weight * weight; // square term weights } void PhraseQuery::normalize(const float_t norm) { weight *= norm; // normalize for query weight *= idf; // factor from document } Scorer* PhraseQuery::scorer(IndexReader& reader) { if (terms.size() == 0) // optimize zero-term case return NULL; if (terms.size() == 1) { // optimize one-term case Term* term = terms.at(0); TermDocs* docs = &reader.termDocs(term); if (docs == NULL) return NULL; return new TermScorer(*docs, reader.getNorms(term->Field()), weight); } int_t tpsLength = terms.size(); TermPositions** tps = new TermPositions*[tpsLength]; for (uint_t i = 0; i < terms.size(); i++) { TermPositions* p = &reader.termPositions(terms.at(i)); if (p == NULL) { while (--i >= 0) delete tps[i]; /* DSR:CL_BUG_LEAK */ delete[] tps; /* DSR:CL_BUG_LEAK */ return NULL; } tps[i] = p; } Scorer* ret = NULL; #ifndef NO_FUZZY_QUERY if (slop != 0) // optimize exact case ret = new SloppyPhraseScorer(tps,tpsLength, slop, reader.getNorms(field), weight); else #endif ret = new ExactPhraseScorer(tps, tpsLength,reader.getNorms(field), weight); delete[] tps; return ret; } //added by search highlighter void PhraseQuery::getTerms(Term**& ret, int_t& size) { size = terms.size(); ret = new Term*[size]; for ( int_t i=0;iText() ); if (i != terms.size()-1) buffer.append(_T(" ")); } buffer.append( _T("\"") ); if (slop != 0) { buffer.append(_T("~")); buffer.append(slop); } if (boost != 1.0f) { buffer.append(_T("^")); buffer.append( boost,10 ); } return buffer.ToString(); } }}