|
a/src/rcldb/searchdata.cpp |
|
b/src/rcldb/searchdata.cpp |
|
... |
|
... |
80 |
if (!(*it)->toNativeQuery(db, &nq, m_stemlang)) {
|
80 |
if (!(*it)->toNativeQuery(db, &nq, m_stemlang)) {
|
81 |
LOGERR(("SearchData::toNativeQuery: failed\n"));
|
81 |
LOGERR(("SearchData::toNativeQuery: failed\n"));
|
82 |
m_reason = (*it)->getReason();
|
82 |
m_reason = (*it)->getReason();
|
83 |
return false;
|
83 |
return false;
|
84 |
}
|
84 |
}
|
85 |
|
85 |
if (nq.empty()) {
|
|
|
86 |
LOGDEB(("SearchData::toNativeQuery: skipping empty clause\n"));
|
|
|
87 |
continue;
|
|
|
88 |
}
|
86 |
// If this structure is an AND list, must use AND_NOT for excl clauses.
|
89 |
// If this structure is an AND list, must use AND_NOT for excl clauses.
|
87 |
// Else this is an OR list, and there can't be excl clauses (checked by
|
90 |
// Else this is an OR list, and there can't be excl clauses (checked by
|
88 |
// addClause())
|
91 |
// addClause())
|
89 |
Xapian::Query::op op;
|
92 |
Xapian::Query::op op;
|
90 |
if (m_tp == SCLT_AND) {
|
93 |
if (m_tp == SCLT_AND) {
|
|
... |
|
... |
189 |
// a single word because there is no white space inside, but are
|
192 |
// a single word because there is no white space inside, but are
|
190 |
// actually multiple terms to rcldb (ie term1,term2)
|
193 |
// actually multiple terms to rcldb (ie term1,term2)
|
191 |
class TextSplitQ : public TextSplit {
|
194 |
class TextSplitQ : public TextSplit {
|
192 |
public:
|
195 |
public:
|
193 |
TextSplitQ(Flags flags, const StopList &_stops)
|
196 |
TextSplitQ(Flags flags, const StopList &_stops)
|
194 |
: TextSplit(flags), stops(_stops), alltermcount(0)
|
197 |
: TextSplit(flags), stops(_stops), alltermcount(0), lastpos(0)
|
195 |
{}
|
198 |
{}
|
196 |
bool takeword(const std::string &interm, int , int, int) {
|
199 |
bool takeword(const std::string &interm, int pos, int, int) {
|
197 |
alltermcount++;
|
200 |
alltermcount++;
|
|
|
201 |
lastpos = pos
|
198 |
LOGDEB1(("TextSplitQ::takeword: %s\n", interm.c_str()));
|
202 |
LOGDEB1(("TextSplitQ::takeword: %s\n", interm.c_str()));
|
199 |
|
203 |
|
200 |
// Check if the first letter is a majuscule in which
|
204 |
// Check if the first letter is a majuscule in which
|
201 |
// case we do not want to do stem expansion. Note that
|
205 |
// case we do not want to do stem expansion. Note that
|
202 |
// the test is convoluted and possibly problematic
|
206 |
// the test is convoluted and possibly problematic
|
|
... |
|
... |
231 |
vector<bool> nostemexps;
|
235 |
vector<bool> nostemexps;
|
232 |
const StopList &stops;
|
236 |
const StopList &stops;
|
233 |
// Count of terms including stopwords: this is for adjusting
|
237 |
// Count of terms including stopwords: this is for adjusting
|
234 |
// phrase/near slack
|
238 |
// phrase/near slack
|
235 |
int alltermcount;
|
239 |
int alltermcount;
|
|
|
240 |
int lastpos;
|
236 |
};
|
241 |
};
|
237 |
|
242 |
|
238 |
// A class used to translate a user compound string (*not* a query
|
243 |
// A class used to translate a user compound string (*not* a query
|
239 |
// language string) as may be entered in any_terms/all_terms search
|
244 |
// language string) as may be entered in any_terms/all_terms search
|
240 |
// entry fields, ex: [term1 "a phrase" term3] into a xapian query
|
245 |
// entry fields, ex: [term1 "a phrase" term3] into a xapian query
|
|
... |
|
... |
454 |
#endif
|
459 |
#endif
|
455 |
}
|
460 |
}
|
456 |
|
461 |
|
457 |
// Generate an appropriate PHRASE/NEAR query with adjusted slack
|
462 |
// Generate an appropriate PHRASE/NEAR query with adjusted slack
|
458 |
// For phrases, give a relevance boost like we do for original terms
|
463 |
// For phrases, give a relevance boost like we do for original terms
|
|
|
464 |
LOGDEB2(("PHRASE/NEAR: alltermcount %d lastpos %d\n",
|
|
|
465 |
splitData->alltermcount, splitData->lastpos));
|
459 |
Xapian::Query xq(op, orqueries.begin(), orqueries.end(),
|
466 |
Xapian::Query xq(op, orqueries.begin(), orqueries.end(),
|
460 |
splitData->alltermcount + slack);
|
467 |
splitData->lastpos + 1 + slack);
|
461 |
if (op == Xapian::Query::OP_PHRASE)
|
468 |
if (op == Xapian::Query::OP_PHRASE)
|
462 |
xq = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, xq,
|
469 |
xq = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, xq,
|
463 |
original_term_wqf_booster);
|
470 |
original_term_wqf_booster);
|
464 |
pqueries.push_back(xq);
|
471 |
pqueries.push_back(xq);
|
465 |
|
472 |
|
|
... |
|
... |
609 |
if (!tr.processUserString(m_text, m_reason, pqueries,
|
616 |
if (!tr.processUserString(m_text, m_reason, pqueries,
|
610 |
db.getStopList()))
|
617 |
db.getStopList()))
|
611 |
return false;
|
618 |
return false;
|
612 |
if (pqueries.empty()) {
|
619 |
if (pqueries.empty()) {
|
613 |
LOGERR(("SearchDataClauseSimple: resolved to null query\n"));
|
620 |
LOGERR(("SearchDataClauseSimple: resolved to null query\n"));
|
614 |
return false;
|
621 |
return true;
|
615 |
}
|
622 |
}
|
616 |
tr.getTerms(m_terms, m_groups);
|
623 |
tr.getTerms(m_terms, m_groups);
|
617 |
tr.getUTerms(m_uterms);
|
624 |
tr.getUTerms(m_uterms);
|
618 |
//listVector("SearchDataClauseSimple: Uterms: ", m_uterms);
|
625 |
//listVector("SearchDataClauseSimple: Uterms: ", m_uterms);
|
619 |
*qp = Xapian::Query(op, pqueries.begin(), pqueries.end());
|
626 |
*qp = Xapian::Query(op, pqueries.begin(), pqueries.end());
|