diff options
author | Geir Storli <geirst@verizonmedia.com> | 2019-11-28 08:28:46 +0000 |
---|---|---|
committer | Geir Storli <geirst@verizonmedia.com> | 2019-11-28 10:15:37 +0000 |
commit | 14035635959cd41fe0dec0ab7b2a4e9206e5a6c9 (patch) | |
tree | 505cdd8ccdd49fd6f4754c7875b921aa490d260a /searchlib/src/vespa/searchlib/query/streaming/querynode.cpp | |
parent | a3b4f9b6060a3987bc57c0faba3b9bcd7930955f (diff) |
Move query classes used in streaming search to separate sub-folder and sub-library.
Diffstat (limited to 'searchlib/src/vespa/searchlib/query/streaming/querynode.cpp')
-rw-r--r-- | searchlib/src/vespa/searchlib/query/streaming/querynode.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp new file mode 100644 index 00000000000..234e64b2718 --- /dev/null +++ b/searchlib/src/vespa/searchlib/query/streaming/querynode.cpp @@ -0,0 +1,160 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "query.h" +#include <vespa/searchlib/parsequery/stackdumpiterator.h> + +#include <vespa/log/log.h> +LOG_SETUP(".vsm.querynode"); + +namespace search { + +namespace { + vespalib::stringref DEFAULT("default"); + bool isPhraseOrNear(const QueryNode * qn) { + return dynamic_cast<const NearQueryNode *> (qn) || dynamic_cast<const PhraseQueryNode *> (qn); + } +} + +QueryNode::UP +QueryNode::Build(const QueryNode * parent, const QueryNodeResultFactory & factory, + SimpleQueryStackDumpIterator & queryRep, bool allowRewrite) +{ + unsigned int arity = queryRep.getArity(); + ParseItem::ItemType type = queryRep.getType(); + UP qn; + switch (type) { + case ParseItem::ITEM_AND: + case ParseItem::ITEM_OR: + case ParseItem::ITEM_WEAK_AND: + case ParseItem::ITEM_EQUIV: + case ParseItem::ITEM_WEIGHTED_SET: + case ParseItem::ITEM_DOT_PRODUCT: + case ParseItem::ITEM_WAND: + case ParseItem::ITEM_NOT: + case ParseItem::ITEM_PHRASE: + case ParseItem::ITEM_SAME_ELEMENT: + case ParseItem::ITEM_NEAR: + case ParseItem::ITEM_ONEAR: + { + qn = QueryConnector::create(type); + if (qn) { + QueryConnector * qc = dynamic_cast<QueryConnector *> (qn.get()); + NearQueryNode * nqn = dynamic_cast<NearQueryNode *> (qc); + if (nqn) { + nqn->distance(queryRep.getArg1()); + } + if ((type == ParseItem::ITEM_WEAK_AND) || + (type == ParseItem::ITEM_WEIGHTED_SET) || + (type == ParseItem::ITEM_DOT_PRODUCT) || + (type == ParseItem::ITEM_SAME_ELEMENT) || + (type == ParseItem::ITEM_WAND)) + { + qn->setIndex(queryRep.getIndexName()); + } + for (size_t i=0; i < arity; i++) { + queryRep.next(); + if (qc->isFlattenable(queryRep.getType())) { + arity += queryRep.getArity(); + } else { + UP child = Build(qc, factory, queryRep, allowRewrite && !isPhraseOrNear(qn.get())); + qc->push_back(std::move(child)); + } + } + } + } + break; + case ParseItem::ITEM_NUMTERM: + case ParseItem::ITEM_TERM: + case ParseItem::ITEM_PREFIXTERM: + case ParseItem::ITEM_REGEXP: + case ParseItem::ITEM_SUBSTRINGTERM: + case ParseItem::ITEM_EXACTSTRINGTERM: + case ParseItem::ITEM_SUFFIXTERM: + case ParseItem::ITEM_PURE_WEIGHTED_STRING: + case ParseItem::ITEM_PURE_WEIGHTED_LONG: + { + vespalib::string index = queryRep.getIndexName(); + if (index.empty()) { + if ((type == ParseItem::ITEM_PURE_WEIGHTED_STRING) || (type == ParseItem::ITEM_PURE_WEIGHTED_LONG)) { + index = parent->getIndex(); + } else { + index = DEFAULT; + } + } + if (dynamic_cast<const SameElementQueryNode *>(parent) != nullptr) { + index = parent->getIndex() + "." + index; + } + vespalib::stringref term = queryRep.getTerm(); + QueryTerm::SearchTerm sTerm(QueryTerm::WORD); + switch (type) { + case ParseItem::ITEM_REGEXP: + sTerm = QueryTerm::REGEXP; + break; + case ParseItem::ITEM_PREFIXTERM: + sTerm = QueryTerm::PREFIXTERM; + break; + case ParseItem::ITEM_SUBSTRINGTERM: + sTerm = QueryTerm::SUBSTRINGTERM; + break; + case ParseItem::ITEM_EXACTSTRINGTERM: + sTerm = QueryTerm::EXACTSTRINGTERM; + break; + case ParseItem::ITEM_SUFFIXTERM: + sTerm = QueryTerm::SUFFIXTERM; + break; + default: + break; + } + QueryTerm::string ssTerm(term); + QueryTerm::string ssIndex(index); + if (ssIndex == "sddocname") { + // This is suboptimal as the term should be checked too. + // But it will do for now as only correct sddocname queries are sent down. + qn.reset(new TrueNode()); + } else { + std::unique_ptr<QueryTerm> qt(new QueryTerm(factory.create(), ssTerm, ssIndex, sTerm)); + qt->setWeight(queryRep.GetWeight()); + qt->setUniqueId(queryRep.getUniqueId()); + if ( qt->encoding().isBase10Integer() || ! qt->encoding().isFloat() || ! factory.getRewriteFloatTerms() || !allowRewrite || (ssTerm.find('.') == vespalib::string::npos)) { + qn = std::move(qt); + } else { + std::unique_ptr<PhraseQueryNode> phrase(new PhraseQueryNode()); + phrase->push_back(UP(new QueryTerm(factory.create(), ssTerm.substr(0, ssTerm.find('.')), ssIndex, QueryTerm::WORD))); + phrase->push_back(UP(new QueryTerm(factory.create(), ssTerm.substr(ssTerm.find('.') + 1), ssIndex, QueryTerm::WORD))); + std::unique_ptr<EquivQueryNode> orqn(new EquivQueryNode()); + orqn->push_back(std::move(qt)); + orqn->push_back(std::move(phrase)); + qn.reset(orqn.release()); + } + } + } + break; + case ParseItem::ITEM_RANK: + { + if (arity >= 1) { + queryRep.next(); + qn = Build(parent, factory, queryRep, false); + for (uint32_t skipCount = arity-1; (skipCount > 0) && queryRep.next(); skipCount--) { + skipCount += queryRep.getArity(); + } + } + } + break; + default: + { + for (uint32_t skipCount = arity; (skipCount > 0) && queryRep.next(); skipCount--) { + skipCount += queryRep.getArity(); + LOG(warning, "Does not understand anything,.... skipping %d", type); + } + } + break; + } + return qn; +} + +const HitList & QueryNode::evaluateHits(HitList & hl) const +{ + return hl; +} + +} |