suggest alternate spellings if no results
This commit is contained in:
@@ -196,6 +196,7 @@ static void noPrefixList(const list<string>& in, list<string>& out)
|
||||
#else
|
||||
#define LOGABS LOGDEB2
|
||||
#endif
|
||||
#if 0
|
||||
static void listList(const string& what, const list<string>&l)
|
||||
{
|
||||
string a;
|
||||
@@ -204,6 +205,7 @@ static void listList(const string& what, const list<string>&l)
|
||||
}
|
||||
LOGDEB(("%s: %s\n", what.c_str(), a.c_str()));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Build a document abstract by extracting text chunks around the query terms
|
||||
// This uses the db termlists, not the original document.
|
||||
|
||||
@@ -22,6 +22,7 @@ static char rcsid[] = "@(#$Id: searchdata.cpp,v 1.32 2008-12-19 09:55:36 dockes
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "xapian.h"
|
||||
|
||||
@@ -173,6 +174,15 @@ bool SearchData::getTerms(vector<string>& terms,
|
||||
(*it)->getTerms(terms, groups, gslks);
|
||||
return true;
|
||||
}
|
||||
// Extract user terms
|
||||
void SearchData::getUTerms(vector<string>& terms) const
|
||||
{
|
||||
for (qlist_cit_t it = m_query.begin(); it != m_query.end(); it++)
|
||||
(*it)->getUTerms(terms);
|
||||
sort(terms.begin(), terms.end());
|
||||
vector<string>::iterator it = unique(terms.begin(), terms.end());
|
||||
terms.erase(it, terms.end());
|
||||
}
|
||||
|
||||
// Splitter callback for breaking a user string into simple terms and
|
||||
// phrases. This is for parts of the user entry which would appear as
|
||||
@@ -249,6 +259,11 @@ public:
|
||||
groups.insert(groups.end(), m_groups.begin(), m_groups.end());
|
||||
return true;
|
||||
}
|
||||
bool getUTerms(vector<string>& terms)
|
||||
{
|
||||
terms.insert(terms.end(), m_uterms.begin(), m_uterms.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void expandTerm(bool dont, const string& term, list<string>& exp,
|
||||
@@ -265,10 +280,22 @@ private:
|
||||
const string& m_stemlang;
|
||||
bool m_doBoostUserTerms;
|
||||
// Single terms and phrases resulting from breaking up text;
|
||||
vector<string> m_uterms;
|
||||
vector<string> m_terms;
|
||||
vector<vector<string> > m_groups;
|
||||
};
|
||||
|
||||
#if 0
|
||||
static void listVector(const string& what, const vector<string>&l)
|
||||
{
|
||||
string a;
|
||||
for (vector<string>::const_iterator it = l.begin(); it != l.end(); it++) {
|
||||
a = a + *it + " ";
|
||||
}
|
||||
LOGDEB(("%s: %s\n", what.c_str(), a.c_str()));
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Expand stem and wildcards
|
||||
*
|
||||
* @param nostemexp don't perform stem expansion. This is mainly used to
|
||||
@@ -300,12 +327,10 @@ void StringToXapianQ::expandTerm(bool nostemexp,
|
||||
if (haswild || m_stemlang.empty())
|
||||
nostemexp = true;
|
||||
|
||||
if (!nostemexp) {
|
||||
}
|
||||
|
||||
if (nostemexp && !haswild) {
|
||||
// Neither stemming nor wildcard expansion: just the word
|
||||
sterm = term;
|
||||
m_uterms.push_back(sterm);
|
||||
exp.push_front(term);
|
||||
exp.resize(1);
|
||||
} else {
|
||||
@@ -314,6 +339,7 @@ void StringToXapianQ::expandTerm(bool nostemexp,
|
||||
m_db.termMatch(Rcl::Db::ET_WILD, m_stemlang, term, l);
|
||||
} else {
|
||||
sterm = term;
|
||||
m_uterms.push_back(sterm);
|
||||
m_db.termMatch(Rcl::Db::ET_STEM, m_stemlang, term, l);
|
||||
}
|
||||
for (list<TermMatchEntry>::const_iterator it = l.begin();
|
||||
@@ -321,6 +347,7 @@ void StringToXapianQ::expandTerm(bool nostemexp,
|
||||
exp.push_back(it->term);
|
||||
}
|
||||
}
|
||||
//listVector("ExpandTerm:uterms now: ", m_uterms);
|
||||
}
|
||||
|
||||
// Do distribution of string vectors: a,b c,d -> a,c a,d b,c b,d
|
||||
@@ -383,10 +410,10 @@ void StringToXapianQ::processSimpleSpan(const string& span, bool nostemexp,
|
||||
// less wqf). This does not happen if there are wildcards anywhere
|
||||
// in the search.
|
||||
if (m_doBoostUserTerms && !sterm.empty()) {
|
||||
xq = Xapian::Query(Xapian::Query::OP_OR,
|
||||
xq,
|
||||
Xapian::Query(m_prefix+sterm,
|
||||
original_term_wqf_booster));
|
||||
xq = Xapian::Query(Xapian::Query::OP_OR,
|
||||
xq,
|
||||
Xapian::Query(m_prefix+sterm,
|
||||
original_term_wqf_booster));
|
||||
}
|
||||
pqueries.push_back(xq);
|
||||
}
|
||||
@@ -468,6 +495,7 @@ bool StringToXapianQ::processUserString(const string &iq,
|
||||
{
|
||||
LOGDEB(("StringToXapianQ:: query string: [%s]\n", iq.c_str()));
|
||||
ermsg.erase();
|
||||
m_uterms.clear();
|
||||
m_terms.clear();
|
||||
m_groups.clear();
|
||||
|
||||
@@ -589,6 +617,8 @@ bool SearchDataClauseSimple::toNativeQuery(Rcl::Db &db, void *p,
|
||||
return false;
|
||||
}
|
||||
tr.getTerms(m_terms, m_groups);
|
||||
tr.getUTerms(m_uterms);
|
||||
//listVector("SearchDataClauseSimple: Uterms: ", m_uterms);
|
||||
*qp = Xapian::Query(op, pqueries.begin(), pqueries.end());
|
||||
return true;
|
||||
}
|
||||
@@ -659,6 +689,7 @@ bool SearchDataClauseDist::toNativeQuery(Rcl::Db &db, void *p,
|
||||
return true;
|
||||
}
|
||||
tr.getTerms(m_terms, m_groups);
|
||||
tr.getUTerms(m_uterms);
|
||||
*qp = *pqueries.begin();
|
||||
return true;
|
||||
}
|
||||
@@ -675,5 +706,9 @@ bool SearchDataClauseSub::getTerms(vector<string>& terms,
|
||||
{
|
||||
return m_sub.getconstptr()->getTerms(terms, groups, gslks);
|
||||
}
|
||||
void SearchDataClauseSub::getUTerms(vector<string>& terms) const
|
||||
{
|
||||
m_sub.getconstptr()->getUTerms(terms);
|
||||
}
|
||||
|
||||
} // Namespace Rcl
|
||||
|
||||
+13
-3
@@ -98,6 +98,9 @@ public:
|
||||
*/
|
||||
bool getTerms(vector<string>& terms,
|
||||
vector<vector<string> >& groups, vector<int>& gslks) const;
|
||||
/** Get user-input terms (before expansion etc.) */
|
||||
void getUTerms(vector<string>& terms) const;
|
||||
|
||||
/**
|
||||
* Get/set the description field which is retrieved from xapian after
|
||||
* initializing the query. It is stored here for usage in the GUI.
|
||||
@@ -140,7 +143,8 @@ public:
|
||||
virtual string getReason() const {return m_reason;}
|
||||
virtual bool getTerms(vector<string>&, vector<vector<string> >&,
|
||||
vector<int>&) const = 0;
|
||||
// {return true;}
|
||||
virtual void getUTerms(vector<string>&) const = 0;
|
||||
|
||||
SClType getTp() {return m_tp;}
|
||||
void setParent(SearchData *p) {m_parentSearch = p;}
|
||||
virtual void setModifiers(Modifier mod) {m_modifiers = mod;}
|
||||
@@ -187,14 +191,19 @@ public:
|
||||
gslks.insert(gslks.end(), m_groups.size(), m_slack);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void getUTerms(vector<string>& terms) const
|
||||
{
|
||||
terms.insert(terms.end(), m_uterms.begin(), m_uterms.end());
|
||||
}
|
||||
protected:
|
||||
string m_text; // Raw user entry text.
|
||||
string m_field; // Field specification if any
|
||||
// Single terms and phrases resulting from breaking up m_text;
|
||||
// valid after toNativeQuery() call
|
||||
vector<string> m_terms;
|
||||
vector<vector<string> > m_groups;
|
||||
vector<vector<string> > m_groups;
|
||||
// User terms before expansion
|
||||
vector<string> m_uterms;
|
||||
// Declare m_slack here. Always 0, but allows getTerms to work for
|
||||
// SearchDataClauseDist
|
||||
int m_slack;
|
||||
@@ -249,6 +258,7 @@ public:
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const string& stemlang);
|
||||
virtual bool getTerms(vector<string>&, vector<vector<string> >&,
|
||||
vector<int>&) const;
|
||||
virtual void getUTerms(vector<string>&) const;
|
||||
protected:
|
||||
RefCntr<SearchData> m_sub;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user