summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorGeir Storli <geirst@yahooinc.com>2022-04-11 11:26:02 +0200
committerGitHub <noreply@github.com>2022-04-11 11:26:02 +0200
commit65dc21685f2286a30c82c7d14c9fe5fe5c42d412 (patch)
treec28d2a5dc1bff4dab1051c163042b84899d2bb2c /searchlib
parent23841f2517967c1a59cf9826f1de953c5caa7199 (diff)
parent16aaf73dc37c63fa92a3298e6c9f8fa6ed32422a (diff)
Merge pull request #21972 from alexeyche/alexeyche/fuzzy-query-annotations
Propagating annotations for fuzzy query [WIP]
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp9
-rw-r--r--searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp4
-rw-r--r--searchlib/src/tests/query/customtypevisitor_test.cpp2
-rw-r--r--searchlib/src/tests/query/query_visitor_test.cpp2
-rw-r--r--searchlib/src/tests/query/querybuilder_test.cpp32
-rw-r--r--searchlib/src/tests/query/streaming_query_test.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/string_search_helper.cpp5
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp14
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.h5
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/query/query_term_simple.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/querynode.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/query/streaming/queryterm.h2
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/querybuilder.h10
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/queryreplicator.h3
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/simplequery.h5
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h4
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/termnodes.h16
19 files changed, 110 insertions, 26 deletions
diff --git a/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp b/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp
index aa64e944baa..947e4aa30c2 100644
--- a/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp
+++ b/searchlib/src/tests/attribute/searchcontext/searchcontext_test.cpp
@@ -402,7 +402,8 @@ SearchContextTest::buildTermQuery(std::vector<char> & buffer, const vespalib::st
{
uint32_t indexLen = index.size();
uint32_t termLen = term.size();
- uint32_t queryPacketSize = 1 + 2 * 4 + indexLen + termLen;
+ uint32_t fuzzyParametersSize = (termType == TermType::FUZZYTERM) ? 8 : 0;
+ uint32_t queryPacketSize = 1 + 2 * 4 + indexLen + termLen + fuzzyParametersSize;
uint32_t p = 0;
buffer.resize(queryPacketSize);
switch (termType) {
@@ -419,6 +420,12 @@ SearchContextTest::buildTermQuery(std::vector<char> & buffer, const vespalib::st
p += vespalib::compress::Integer::compressPositive(termLen, &buffer[p]);
memcpy(&buffer[p], term.c_str(), termLen);
p += termLen;
+
+ if (termType == TermType::FUZZYTERM) {
+ p += vespalib::compress::Integer::compressPositive(2, &buffer[p]); // max edit distance
+ p += vespalib::compress::Integer::compressPositive(0, &buffer[p]); // prefix length
+ }
+
buffer.resize(p);
}
diff --git a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp
index 1f570e0a381..4deb287df0e 100644
--- a/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp
+++ b/searchlib/src/tests/attribute/stringattribute/stringattribute_test.cpp
@@ -388,8 +388,8 @@ testSingleValue(Attribute & svsa, Config &cfg)
TEST("testSingleValue")
{
EXPECT_EQUAL(24u, sizeof(SearchContext));
- EXPECT_EQUAL(56u, sizeof(StringSearchHelper));
- EXPECT_EQUAL(104u, sizeof(attribute::SingleStringEnumSearchContext));
+ EXPECT_EQUAL(88u, sizeof(StringSearchHelper));
+ EXPECT_EQUAL(136u, sizeof(attribute::SingleStringEnumSearchContext));
{
Config cfg(BasicType::STRING, CollectionType::SINGLE);
SingleValueStringAttribute svsa("svsa", cfg);
diff --git a/searchlib/src/tests/query/customtypevisitor_test.cpp b/searchlib/src/tests/query/customtypevisitor_test.cpp
index 0e8155e23c3..b1e979b5bcb 100644
--- a/searchlib/src/tests/query/customtypevisitor_test.cpp
+++ b/searchlib/src/tests/query/customtypevisitor_test.cpp
@@ -36,7 +36,7 @@ struct MyRangeTerm : InitTerm<RangeTerm> {};
struct MyStringTerm : InitTerm<StringTerm> {};
struct MySubstrTerm : InitTerm<SubstringTerm> {};
struct MySuffixTerm : InitTerm<SuffixTerm> {};
-struct MyFuzzyTerm : InitTerm<FuzzyTerm> {};
+struct MyFuzzyTerm : FuzzyTerm { MyFuzzyTerm(): FuzzyTerm("term", "view", 0, Weight(0), 2, 0) {} };
struct MyWeakAnd : WeakAnd { MyWeakAnd() : WeakAnd(1234, "view") {} };
struct MyWeightedSetTerm : WeightedSetTerm { MyWeightedSetTerm() : WeightedSetTerm(0, "view", 0, Weight(42)) {} };
struct MyDotProduct : DotProduct { MyDotProduct() : DotProduct(0, "view", 0, Weight(42)) {} };
diff --git a/searchlib/src/tests/query/query_visitor_test.cpp b/searchlib/src/tests/query/query_visitor_test.cpp
index f770213e8e5..8e8be997be0 100644
--- a/searchlib/src/tests/query/query_visitor_test.cpp
+++ b/searchlib/src/tests/query/query_visitor_test.cpp
@@ -86,7 +86,7 @@ TEST("requireThatAllNodesCanBeVisited") {
checkVisit<NearestNeighborTerm>(new SimpleNearestNeighborTerm("query_tensor", "doc_tensor", 0, Weight(0), 123, true, 321, 100100.25));
checkVisit<TrueQueryNode>(new SimpleTrue());
checkVisit<FalseQueryNode>(new SimpleFalse());
- checkVisit<FuzzyTerm>(new SimpleFuzzyTerm("t", "field", 0, Weight(0)));
+ checkVisit<FuzzyTerm>(new SimpleFuzzyTerm("t", "field", 0, Weight(0), 2, 0));
}
} // namespace
diff --git a/searchlib/src/tests/query/querybuilder_test.cpp b/searchlib/src/tests/query/querybuilder_test.cpp
index 2ea566027c4..5b410879fa0 100644
--- a/searchlib/src/tests/query/querybuilder_test.cpp
+++ b/searchlib/src/tests/query/querybuilder_test.cpp
@@ -7,6 +7,8 @@
#include <vespa/searchlib/query/tree/querybuilder.h>
#include <vespa/searchlib/query/tree/simplequery.h>
#include <vespa/searchlib/query/tree/stackdumpcreator.h>
+#include <vespa/searchlib/query/query_term_decoder.h>
+#include <vespa/searchlib/query/query_term_simple.h>
#include <vespa/vespalib/testkit/test_kit.h>
#include <vespa/log/log.h>
@@ -115,7 +117,7 @@ Node::UP createQueryTree() {
builder.add_true_node();
builder.add_false_node();
}
- builder.addFuzzyTerm(str[5], view[5], id[5], weight[5]);
+ builder.addFuzzyTerm(str[5], view[5], id[5], weight[5], 3, 1);
}
Node::UP node = builder.build();
ASSERT_TRUE(node.get());
@@ -311,6 +313,8 @@ void checkQueryTreeTypes(Node *node) {
auto* fuzzy_term = as_node<FuzzyTerm>(and_node->getChildren()[12]);
EXPECT_TRUE(checkTerm(fuzzy_term, str[5], view[5], id[5], weight[5]));
+ EXPECT_EQUAL(3u, fuzzy_term->getMaxEditDistance());
+ EXPECT_EQUAL(1u, fuzzy_term->getPrefixLength());
}
struct AbstractTypes {
@@ -434,8 +438,9 @@ struct MyNearestNeighborTerm : NearestNeighborTerm {
struct MyTrue : TrueQueryNode {};
struct MyFalse : FalseQueryNode {};
struct MyFuzzyTerm : FuzzyTerm {
- MyFuzzyTerm(const Type &t, const string &f, int32_t i, Weight w)
- : FuzzyTerm(t, f, i, w) {
+ MyFuzzyTerm(const Type &t, const string &f, int32_t i, Weight w,
+ uint32_t m, uint32_t p)
+ : FuzzyTerm(t, f, i, w, m, p) {
}
};
@@ -578,6 +583,7 @@ TEST("require that Query Tree Creator Can Replicate Queries") {
TEST("require that Query Tree Creator Can Create Queries From Stack") {
Node::UP node = createQueryTree<MyQueryNodeTypes>();
string stackDump = StackDumpCreator::create(*node);
+
SimpleQueryStackDumpIterator iterator(stackDump);
Node::UP new_node = QueryTreeCreator<SimpleQueryNodeTypes>::create(iterator);
@@ -618,6 +624,26 @@ TEST("require that All Range Syntaxes Work") {
EXPECT_TRUE(range2 == range_term->getTerm());
}
+TEST("require that fuzzy node can be created") {
+ QueryBuilder<SimpleQueryNodeTypes> builder;
+ builder.addFuzzyTerm("term", "view", 0, Weight(0), 3, 1);
+ Node::UP node = builder.build();
+
+ string stackDump = StackDumpCreator::create(*node);
+ {
+ SimpleQueryStackDumpIterator iterator(stackDump);
+ Node::UP new_node = QueryTreeCreator<SimpleQueryNodeTypes>::create(iterator);
+ FuzzyTerm *fuzzy_node = as_node<FuzzyTerm>(new_node.get());
+ EXPECT_EQUAL(3u, fuzzy_node->getMaxEditDistance());
+ EXPECT_EQUAL(1u, fuzzy_node->getPrefixLength());
+ }
+ {
+ search::QueryTermSimple::UP queryTermSimple = search::QueryTermDecoder::decodeTerm(stackDump);
+ EXPECT_EQUAL(3u, queryTermSimple->getFuzzyMaxEditDistance());
+ EXPECT_EQUAL(1u, queryTermSimple->getFuzzyPrefixLength());
+ }
+}
+
TEST("require that empty intermediate node can be added") {
QueryBuilder<SimpleQueryNodeTypes> builder;
builder.addAnd(0);
diff --git a/searchlib/src/tests/query/streaming_query_test.cpp b/searchlib/src/tests/query/streaming_query_test.cpp
index ec292eda8eb..4b5433dd370 100644
--- a/searchlib/src/tests/query/streaming_query_test.cpp
+++ b/searchlib/src/tests/query/streaming_query_test.cpp
@@ -805,9 +805,9 @@ TEST("testSameElementEvaluate") {
}
TEST("Control the size of query terms") {
- EXPECT_EQUAL(104u, sizeof(QueryTermSimple));
- EXPECT_EQUAL(120u, sizeof(QueryTermUCS4));
- EXPECT_EQUAL(264u, sizeof(QueryTerm));
+ EXPECT_EQUAL(112u, sizeof(QueryTermSimple));
+ EXPECT_EQUAL(128u, sizeof(QueryTermUCS4));
+ EXPECT_EQUAL(272u, sizeof(QueryTerm));
}
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/attribute/string_search_helper.cpp b/searchlib/src/vespa/searchlib/attribute/string_search_helper.cpp
index d876d80e73f..cd233b75438 100644
--- a/searchlib/src/vespa/searchlib/attribute/string_search_helper.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/string_search_helper.cpp
@@ -27,7 +27,10 @@ StringSearchHelper::StringSearchHelper(QueryTermUCS4 & term, bool cased)
_term._char = term.getTerm();
_termLen = term.getTermLen();
} else if (isFuzzy()) {
- _fuzzyMatcher = vespalib::FuzzyMatcher::from_term(term.getTerm());
+ _fuzzyMatcher = vespalib::FuzzyMatcher::from_term(
+ term.getTerm(),
+ term.getFuzzyMaxEditDistance(),
+ term.getFuzzyPrefixLength());
} else {
term.term(_term._ucs4);
}
diff --git a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
index 85b55284b35..f625a2b7fd2 100644
--- a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
+++ b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
@@ -170,7 +170,6 @@ bool SimpleQueryStackDumpIterator::readNext() {
case ParseItem::ITEM_EXACTSTRINGTERM:
case ParseItem::ITEM_SUFFIXTERM:
case ParseItem::ITEM_REGEXP:
- case ParseItem::ITEM_FUZZY:
_curr_index_name = read_stringref(p);
_curr_term = read_stringref(p);
_currArity = 0;
@@ -188,6 +187,9 @@ bool SimpleQueryStackDumpIterator::readNext() {
case ParseItem::ITEM_NEAREST_NEIGHBOR:
if ( ! readNN(p)) return false;
break;
+ case ParseItem::ITEM_FUZZY:
+ if (!readFuzzy(p)) return false;
+ break;
case ParseItem::ITEM_TRUE:
case ParseItem::ITEM_FALSE:
// no content
@@ -256,4 +258,14 @@ SimpleQueryStackDumpIterator::readComplexTerm(const char *& p) {
return true;
}
+bool
+SimpleQueryStackDumpIterator::readFuzzy(const char *&p) {
+ _curr_index_name = read_stringref(p);
+ _curr_term = read_stringref(p); // fuzzy term
+ _extraIntArg1 = readCompressedPositiveInt(p); // maxEditDistance
+ _extraIntArg2 = readCompressedPositiveInt(p); // prefixLength
+ _currArity = 0;
+ return true;
+}
+
}
diff --git a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.h b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.h
index 5cec16000b7..ca3e3f6be10 100644
--- a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.h
+++ b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.h
@@ -54,6 +54,7 @@ private:
VESPA_DLL_LOCAL bool readPredicate(const char *&p);
VESPA_DLL_LOCAL bool readNN(const char *&p);
VESPA_DLL_LOCAL bool readComplexTerm(const char *& p);
+ VESPA_DLL_LOCAL bool readFuzzy(const char *&p);
VESPA_DLL_LOCAL bool readNext();
public:
/**
@@ -115,6 +116,10 @@ public:
bool getAllowApproximate() const { return (_extraIntArg2 != 0); }
uint32_t getExploreAdditionalHits() const { return _extraIntArg3; }
+ // fuzzy match arguments
+ uint32_t getFuzzyMaxEditDistance() const { return _extraIntArg1; }
+ uint32_t getFuzzyPrefixLength() const { return _extraIntArg2; }
+
query::PredicateQueryTerm::UP getPredicateQueryTerm() { return std::move(_predicate_query_term); }
vespalib::stringref getIndexName() const { return _curr_index_name; }
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
index e0fcc8b690c..17e50216a23 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.cpp
@@ -210,7 +210,9 @@ QueryTermSimple::QueryTermSimple(const string & term_, Type type)
_diversityCutoffStrict(false),
_valid(true),
_term(term_),
- _diversityAttribute()
+ _diversityAttribute(),
+ _fuzzyMaxEditDistance(2),
+ _fuzzyPrefixLength(0)
{
if (isFullRange(_term)) {
stringref rest(_term.c_str() + 1, _term.size() - 2);
diff --git a/searchlib/src/vespa/searchlib/query/query_term_simple.h b/searchlib/src/vespa/searchlib/query/query_term_simple.h
index 0d5dd116826..b84813cd12e 100644
--- a/searchlib/src/vespa/searchlib/query/query_term_simple.h
+++ b/searchlib/src/vespa/searchlib/query/query_term_simple.h
@@ -52,6 +52,8 @@ public:
size_t getDiversityCutoffGroups() const { return _diversityCutoffGroups; }
bool getDiversityCutoffStrict() const { return _diversityCutoffStrict; }
vespalib::stringref getDiversityAttribute() const { return _diversityAttribute; }
+ size_t getFuzzyMaxEditDistance() const { return _fuzzyMaxEditDistance; }
+ size_t getFuzzyPrefixLength() const { return _fuzzyPrefixLength; }
bool getAsIntegerTerm(int64_t & lower, int64_t & upper) const;
bool getAsDoubleTerm(double & lower, double & upper) const;
const char * getTerm() const { return _term.c_str(); }
@@ -68,6 +70,7 @@ public:
vespalib::string getClassName() const;
bool isValid() const { return _valid; }
const string & getTermString() const { return _term; }
+
private:
bool getRangeInternal(int64_t & low, int64_t & high) const;
template <typename N>
@@ -84,6 +87,10 @@ private:
stringref _diversityAttribute;
template <typename T, typename D>
bool getAsNumericTerm(T & lower, T & upper, D d) const;
+
+protected:
+ uint32_t _fuzzyMaxEditDistance; // set in QueryTerm
+ uint32_t _fuzzyPrefixLength;
};
}
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
index 6f126c7a3eb..6d59886a4f5 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
+++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp
@@ -140,6 +140,10 @@ QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factor
auto qt = std::make_unique<QueryTerm>(factory.create(), ssTerm, ssIndex, sTerm);
qt->setWeight(queryRep.GetWeight());
qt->setUniqueId(queryRep.getUniqueId());
+ if (qt->isFuzzy()) {
+ qt->setFuzzyMaxEditDistance(queryRep.getFuzzyMaxEditDistance());
+ qt->setFuzzyPrefixLength(queryRep.getFuzzyPrefixLength());
+ }
if (qt->encoding().isBase10Integer() ||
! qt->encoding().isFloat() ||
! factory.getRewriteFloatTerms() ||
diff --git a/searchlib/src/vespa/searchlib/query/streaming/queryterm.h b/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
index 25f2b598413..af32458c5da 100644
--- a/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
+++ b/searchlib/src/vespa/searchlib/query/streaming/queryterm.h
@@ -85,6 +85,8 @@ public:
void visitMembers(vespalib::ObjectVisitor &visitor) const override;
void setIndex(const string & index_) override { _index = index_; }
const string & getIndex() const override { return _index; }
+ void setFuzzyMaxEditDistance(uint32_t fuzzyMaxEditDistance) { _fuzzyMaxEditDistance = fuzzyMaxEditDistance; }
+ void setFuzzyPrefixLength(uint32_t fuzzyPrefixLength) { _fuzzyPrefixLength = fuzzyPrefixLength; }
protected:
using QueryNodeResultBaseContainer = std::unique_ptr<QueryNodeResultBase>;
string _index;
diff --git a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h
index ee3a944cce1..2273dadbfcf 100644
--- a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h
+++ b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h
@@ -222,8 +222,9 @@ create_nearest_neighbor_term(vespalib::stringref query_tensor_name, vespalib::st
}
template <class NodeTypes>
typename NodeTypes::FuzzyTerm *
-createFuzzyTerm(vespalib::stringref term, vespalib::stringref view, int32_t id, Weight weight) {
- return new typename NodeTypes::FuzzyTerm(term, view, id, weight);
+createFuzzyTerm(vespalib::stringref term, vespalib::stringref view, int32_t id, Weight weight,
+ uint32_t maxEditDistance, uint32_t prefixLength) {
+ return new typename NodeTypes::FuzzyTerm(term, view, id, weight, maxEditDistance, prefixLength);
}
@@ -333,9 +334,10 @@ public:
adjustWeight(weight);
return addTerm(createRegExpTerm<NodeTypes>(term, view, id, weight));
}
- typename NodeTypes::FuzzyTerm &addFuzzyTerm(stringref term, stringref view, int32_t id, Weight weight) {
+ typename NodeTypes::FuzzyTerm &addFuzzyTerm(stringref term, stringref view, int32_t id, Weight weight,
+ uint32_t maxEditDistance, uint32_t prefixLength) {
adjustWeight(weight);
- return addTerm(createFuzzyTerm<NodeTypes>(term, view, id, weight));
+ return addTerm(createFuzzyTerm<NodeTypes>(term, view, id, weight, maxEditDistance, prefixLength));
}
typename NodeTypes::NearestNeighborTerm &add_nearest_neighbor_term(stringref query_tensor_name, stringref field_name,
int32_t id, Weight weight, uint32_t target_num_hits,
diff --git a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
index ecaee350b21..52cfbc5effb 100644
--- a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
@@ -197,7 +197,8 @@ private:
void visit(FuzzyTerm &node) override {
replicate(node, _builder.addFuzzyTerm(
node.getTerm(), node.getView(),
- node.getId(), node.getWeight()));
+ node.getId(), node.getWeight(),
+ node.getMaxEditDistance(), node.getPrefixLength()));
}
};
diff --git a/searchlib/src/vespa/searchlib/query/tree/simplequery.h b/searchlib/src/vespa/searchlib/query/tree/simplequery.h
index 00dad2597ce..05e731c0c5c 100644
--- a/searchlib/src/vespa/searchlib/query/tree/simplequery.h
+++ b/searchlib/src/vespa/searchlib/query/tree/simplequery.h
@@ -154,8 +154,9 @@ struct SimpleNearestNeighborTerm : NearestNeighborTerm {
};
struct SimpleFuzzyTerm : FuzzyTerm {
SimpleFuzzyTerm(const Type &term, vespalib::stringref view,
- int32_t id, Weight weight)
- : FuzzyTerm(term, view, id, weight) {
+ int32_t id, Weight weight,
+ uint32_t maxEditDistance, uint32_t prefixLength)
+ : FuzzyTerm(term, view, id, weight, maxEditDistance, prefixLength) {
}
~SimpleFuzzyTerm() override;
};
diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp
index f36410d1845..5ed33ec18a1 100644
--- a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp
@@ -280,6 +280,8 @@ class QueryNodeConverter : public QueryVisitor {
void visit(FuzzyTerm &node) override {
createTerm(node, ParseItem::ITEM_FUZZY);
+ appendCompressedPositiveNumber(node.getMaxEditDistance());
+ appendCompressedPositiveNumber(node.getPrefixLength());
}
void visit(NearestNeighborTerm &node) override {
diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h
index a5f3be3e618..4103c3b1766 100644
--- a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h
@@ -198,7 +198,9 @@ private:
} else if (type == ParseItem::ITEM_REGEXP) {
t = &builder.addRegExpTerm(term, view, id, weight);
} else if (type == ParseItem::ITEM_FUZZY) {
- t = &builder.addFuzzyTerm(term, view, id, weight);
+ uint32_t maxEditDistance = queryStack.getFuzzyMaxEditDistance();
+ uint32_t prefixLength = queryStack.getFuzzyPrefixLength();
+ t = &builder.addFuzzyTerm(term, view, id, weight, maxEditDistance, prefixLength);
} else {
vespalib::Issue::report("query builder: Unable to create query tree from stack dump. node type = %d.", type);
}
diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.h b/searchlib/src/vespa/searchlib/query/tree/termnodes.h
index 7aa867e25ed..5604a3afb52 100644
--- a/searchlib/src/vespa/searchlib/query/tree/termnodes.h
+++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.h
@@ -117,13 +117,21 @@ public:
//-----------------------------------------------------------------------------
-class FuzzyTerm : public QueryNodeMixin<FuzzyTerm, StringBase>
-{
+class FuzzyTerm : public QueryNodeMixin<FuzzyTerm, StringBase> {
+private:
+ uint32_t _maxEditDistance;
+ uint32_t _prefixLength;
public:
FuzzyTerm(const Type &term, vespalib::stringref view,
- int32_t id, Weight weight)
- : QueryNodeMixinType(term, view, id, weight)
+ int32_t id, Weight weight, uint32_t maxEditDistance, uint32_t prefixLength)
+ : QueryNodeMixinType(term, view, id, weight),
+ _maxEditDistance(maxEditDistance),
+ _prefixLength(prefixLength)
{}
+
+ uint32_t getMaxEditDistance() const { return _maxEditDistance; }
+ uint32_t getPrefixLength() const { return _prefixLength; }
+
virtual ~FuzzyTerm() = 0;
};