query-parser: special-case wildcards
We were transforming wild-card searches into regular-expression searches; while that works, it's also significantly slower. So, instead, special-case wildcards, and use the Xapian machinery for wildcard queries.
This commit is contained in:
@ -167,14 +167,9 @@ data (Mux::Tokens& tokens, ProcPtr proc, WarningVec& warnings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// does it look like a regexp?
|
// does it look like a regexp?
|
||||||
if (val.length()>=2) {
|
if (val.length() >=2 )
|
||||||
if (val[0]=='/' && val[val.length()-1] == '/')
|
if (val[0] == '/' && val[val.length()-1] == '/')
|
||||||
return regex (fields, val, token.pos, proc, warnings);
|
return regex (fields, val, token.pos, proc, warnings);
|
||||||
else if (val[val.length()-1] == '*')
|
|
||||||
return regex (fields, // transfrom wildcard into regexp
|
|
||||||
"/" + val.substr(0, val.length()-1) + ".*/",
|
|
||||||
token.pos, proc, warnings);
|
|
||||||
}
|
|
||||||
|
|
||||||
// does it look like a range?
|
// does it look like a range?
|
||||||
const auto dotdot = val.find("..");
|
const auto dotdot = val.find("..");
|
||||||
|
|||||||
@ -48,18 +48,30 @@ xapian_query_op (const Mux::Tree& tree)
|
|||||||
return Xapian::Query(op, childvec.begin(), childvec.end());
|
return Xapian::Query(op, childvec.begin(), childvec.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Xapian::Query
|
||||||
|
maybe_wildcard (const Value* val, const std::string& str)
|
||||||
|
{
|
||||||
|
const auto vlen = str.length();
|
||||||
|
if (vlen <= 1 || str[vlen-1] != '*')
|
||||||
|
return Xapian::Query(val->prefix + str);
|
||||||
|
else
|
||||||
|
return Xapian::Query(Xapian::Query::OP_WILDCARD,
|
||||||
|
val->prefix + str.substr(0, vlen-1));
|
||||||
|
}
|
||||||
|
|
||||||
static Xapian::Query
|
static Xapian::Query
|
||||||
xapian_query_value (const Mux::Tree& tree)
|
xapian_query_value (const Mux::Tree& tree)
|
||||||
{
|
{
|
||||||
const auto v = dynamic_cast<Value*> (tree.node.data.get());
|
const auto v = dynamic_cast<Value*> (tree.node.data.get());
|
||||||
if (!v->phrase)
|
if (!v->phrase)
|
||||||
return Xapian::Query(v->prefix + v->value);
|
return maybe_wildcard(v, v->value);
|
||||||
|
|
||||||
const auto parts = split (v->value, " ");
|
const auto parts = split (v->value, " ");
|
||||||
|
|
||||||
std::vector<Xapian::Query> phvec;
|
std::vector<Xapian::Query> phvec;
|
||||||
for (const auto p: parts)
|
for (const auto p: parts)
|
||||||
phvec.push_back(Xapian::Query(v->prefix + p));
|
phvec.emplace_back(maybe_wildcard(v, p));
|
||||||
|
|
||||||
if (parts.empty())
|
if (parts.empty())
|
||||||
return Xapian::Query::MatchNothing; // shouldn't happen
|
return Xapian::Query::MatchNothing; // shouldn't happen
|
||||||
|
|||||||
Reference in New Issue
Block a user