在firtex大家反映说phrasequery无效。所以跟踪了一下。
不知道是不是我的版本有问题,从代码来看
Query* q = QueryParser::parse(line,field,pAnalyzer,false);
是不可能解析为PhraseQuery.因为都解析为布尔查询了(或者词项查询)
Query* QueryParser::getFieldQuery(const tstring& sField, const tstring& sQueryText)
{
.....
if (pTokens->getNumTokens() <= 0)
{
return NULL;
}
else
{
if(m_pHandler)
{
Query* pQuery = m_pHandler->createFieldQuery(sField.c_str(),pTokens);
if(pQuery)
return pQuery;
}
if (pTokens->getNumTokens() == 1)
{
Tokens::Iterator::AutoPtr pIter(pTokens->iterator());
Term* pTerm = pIter->next()->toTerm(sField.c_str());
Query* pRetQuery = new TermQuery(pTerm);
delete pTerm;
return pRetQuery;
}
else if(pTokens->hasPositionIncrement())
{
BooleanQuery* pAndQuery = NULL;
BooleanQuery* pOrQuery = NULL;
TermQuery* pTermQuery = NULL;
Tokens::Iterator::AutoPtr pIter(pTokens->iterator());
while (pIter->hasNext())
{
Token* pToken = pIter->next();
Term::AutoPtr pTerm(pToken->toTerm(sField.c_str()));
pTermQuery = new TermQuery(pTerm.get());
if(pToken->getPositionIncrement() >= 1)
{
if(!pAndQuery)
pAndQuery = new BooleanQuery;
pAndQuery->add(pTermQuery, true, false);
}
else
{
if(!pOrQuery)
pOrQuery = new BooleanQuery;
if(pAndQuery->getClauseCount() == 1)
{
BooleanClause *pClause = pAndQuery->getClauses()[0];
pClause->setRequired(false);
pOrQuery->add(pClause);
pAndQuery->getClauses().clear();
pAndQuery->add(pTermQuery, true, false);
}
else if(pAndQuery->getClauseCount() > 1)
{
pOrQuery->add(pAndQuery, false, false);
pAndQuery = new BooleanQuery;
pAndQuery->add(pTermQuery, true, false);
}
}
}//end while
if(pOrQuery)
{
pOrQuery->add(pAndQuery, false, false);
pAndQuery = NULL;
}
return pOrQuery ? pOrQuery : pAndQuery;
}
else
{
BooleanQuery* pAndQuery = new BooleanQuery;
Token* pToken;
Tokens::Iterator::AutoPtr pIter(pTokens->iterator());
while (pIter->hasNext())
{
pToken = pIter->next();
Term::AutoPtr pTerm(pToken->toTerm(sField.c_str()));
pAndQuery->add(new TermQuery(pTerm.get()), true, false);
}
return pAndQuery;
}
}
return NULL;
}
临时做了如下修改,自己调用解析器,填充构建phrasequery,不用QueryParser::parse:
PhraseQuery *q = new PhraseQuery;
StringReader reader(line);// line = query
Tokens* pTokens = NULL;
pTokens = pAnalyzer->nextTokens(&reader);
Token* pToken;
Tokens::Iterator::AutoPtr pIter(pTokens->iterator());
while (pIter->hasNext())
{
pToken = pIter->next();
Term::AutoPtr pTerm(pToken->toTerm(field));
q->addTerm(pTerm);
//pAndQuery->add(new TermQuery(pTerm.get()), true, false);
}
QueryHits* pHits = pSearcher->search(q,100);
实验可行