summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@oath.com>2018-08-15 09:28:42 +0200
committerHenning Baldersheim <balder@oath.com>2018-08-27 09:22:14 +0200
commitbe6729d2eadb3abe61613acb82c59a137ccf12a0 (patch)
tree7e648f022c922ce8cc700bff77089a2aa2527ce0 /searchcore
parent73ed7ad7c3cbd41d5ca44c4f2f7ae547fe4c5abe (diff)
- Add option to increment an attribute for every doc matched.
- Add option to increment an attribute for every doc reranked. - Add option to increment an attribute for every doc fetched. Conflicts: searchcore/src/vespa/searchcore/proton/matching/attribute_operation.cpp Conflicts: searchlib/src/vespa/searchlib/attribute/i_attribute_functor.h
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/matching/matching_test.cpp18
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp11
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h2
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp12
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp8
-rw-r--r--searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h8
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_master.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp23
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp72
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/match_tools.h27
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/matcher.cpp29
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/matcher.h14
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/matchview.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/searchview.cpp7
-rw-r--r--searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h1
17 files changed, 199 insertions, 47 deletions
diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp
index 293d87870e5..8d75c8b8d24 100644
--- a/searchcore/src/tests/proton/matching/matching_test.cpp
+++ b/searchcore/src/tests/proton/matching/matching_test.cpp
@@ -327,10 +327,14 @@ struct MyWorld {
}
};
+ struct DummyAttributeExecutor : public IAttributeExecutor {
+ void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override {}
+ };
void verify_diversity_filter(SearchRequest::SP req, bool expectDiverse) {
Matcher::SP matcher = createMatcher();
search::fef::Properties overrides;
- auto mtf = matcher->create_match_tools_factory(*req, searchContext, attributeContext, metaStore, overrides);
+ DummyAttributeExecutor attrExec;
+ auto mtf = matcher->create_match_tools_factory(*req, searchContext, attributeContext, attrExec, metaStore, overrides);
auto diversity = mtf->createDiversifier();
EXPECT_EQUAL(expectDiverse, static_cast<bool>(diversity));
}
@@ -339,8 +343,9 @@ struct MyWorld {
Matcher::SP matcher = createMatcher();
SearchRequest::SP request = createSimpleRequest("f1", "spread");
search::fef::Properties overrides;
+ DummyAttributeExecutor attrExec;
MatchToolsFactory::UP match_tools_factory = matcher->create_match_tools_factory(
- *request, searchContext, attributeContext, metaStore, overrides);
+ *request, searchContext, attributeContext, attrExec, metaStore, overrides);
MatchTools::UP match_tools = match_tools_factory->createMatchTools();
match_tools->setup_first_phase();
return match_tools->match_data().get_termwise_limit();
@@ -353,8 +358,9 @@ struct MyWorld {
owned_objects.context.reset(new MatchContext(std::make_unique<MyAttributeContext>(),
std::make_unique<FakeSearchContext>()));
vespalib::SimpleThreadBundle threadBundle(threads);
+ DummyAttributeExecutor attrExec;
SearchReply::UP reply = matcher->match(*req, threadBundle, searchContext, attributeContext,
- *sessionManager, metaStore, std::move(owned_objects));
+ attrExec, *sessionManager, metaStore, std::move(owned_objects));
matchingStats.add(matcher->getStats());
return reply;
}
@@ -386,12 +392,14 @@ struct MyWorld {
FeatureSet::SP getSummaryFeatures(DocsumRequest::SP req) {
Matcher::SP matcher = createMatcher();
- return matcher->getSummaryFeatures(*req, searchContext, attributeContext, *sessionManager);
+ DummyAttributeExecutor attrExec;
+ return matcher->getSummaryFeatures(*req, searchContext, attributeContext, attrExec, *sessionManager);
}
FeatureSet::SP getRankFeatures(DocsumRequest::SP req) {
Matcher::SP matcher = createMatcher();
- return matcher->getRankFeatures(*req, searchContext, attributeContext, *sessionManager);
+ DummyAttributeExecutor attrExec;
+ return matcher->getRankFeatures(*req, searchContext, attributeContext, attrExec, *sessionManager);
}
};
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp
index d0a1e891150..f08300ba3c6 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.cpp
@@ -581,6 +581,17 @@ AttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor> func)
}
}
+void
+AttributeManager::asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const {
+ AttributeMap::const_iterator itr = _attributes.find(name);
+ if (itr == _attributes.end() || itr->second.isExtra() || !func) {
+ return;
+ }
+ AttributeVector::SP attrsp = itr->second.getAttribute();
+ _attributeFieldWriter.execute(_attributeFieldWriter.getExecutorId(attrsp->getNamePrefix()),
+ [attrsp, func]() { (*func)(*attrsp); });
+}
+
ExclusiveAttributeReadAccessor::UP
AttributeManager::getExclusiveReadAccessor(const vespalib::string &name) const
{
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h
index bf0258deffc..1ddba45ac46 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/attributemanager.h
@@ -176,6 +176,7 @@ public:
const std::vector<search::AttributeVector *> &getWritableAttributes() const override;
void asyncForEachAttribute(std::shared_ptr<IAttributeFunctor> func) const override;
+ void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override;
ExclusiveAttributeReadAccessor::UP getExclusiveReadAccessor(const vespalib::string &name) const override;
@@ -185,3 +186,4 @@ public:
};
} // namespace proton
+
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp
index 48332bedbb7..e8878b29678 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp
+++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.cpp
@@ -200,6 +200,18 @@ FilterAttributeManager::asyncForEachAttribute(std::shared_ptr<IAttributeFunctor>
}
}
+void
+FilterAttributeManager::asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const {
+ AttributeGuard::UP attr = _mgr->getAttribute(name);
+ if (!attr) { return; }
+ search::ISequencedTaskExecutor &attributeFieldWriter = getAttributeFieldWriter();
+ attributeFieldWriter.execute(attributeFieldWriter.getExecutorId((*attr)->getNamePrefix()),
+ [attr=std::move(attr), func]() mutable {
+ (*func)(dynamic_cast<const search::AttributeVector&>(*attr));
+ });
+
+}
+
ExclusiveAttributeReadAccessor::UP
FilterAttributeManager::getExclusiveReadAccessor(const vespalib::string &name) const
{
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h
index f6a67a5ae3c..918432ddcd7 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/filter_attribute_manager.h
@@ -54,6 +54,9 @@ public:
ExclusiveAttributeReadAccessor::UP getExclusiveReadAccessor(const vespalib::string &name) const override;
void setImportedAttributes(std::unique_ptr<ImportedAttributesRepo> attributes) override;
const ImportedAttributesRepo *getImportedAttributes() const override;
+
+ void asyncForAttribute(const vespalib::string &name, std::shared_ptr<IAttributeFunctor> func) const override;
};
} // namespace proton
+
diff --git a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h
index dd8f9a5df90..6df9b207281 100644
--- a/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h
+++ b/searchcore/src/vespa/searchcore/proton/attribute/i_attribute_manager.h
@@ -5,6 +5,7 @@
#include "attribute_collection_spec.h"
#include "exclusive_attribute_read_accessor.h"
#include "i_attribute_factory.h"
+#include <vespa/searchlib/attribute/i_attribute_functor.h>
#include <vespa/searchcorespi/flush/iflushtarget.h>
#include <vespa/searchlib/attribute/iattributemanager.h>
#include <vespa/searchlib/common/serialnum.h>
@@ -25,7 +26,7 @@ class ImportedAttributesRepo;
* The attribute manager should handle initialization and loading of attribute vectors,
* and then provide access to the attributes for feeding, searching and flushing.
*/
-struct IAttributeManager : public search::IAttributeManager
+struct IAttributeManager : public search::IAttributeManager, public search::attribute::IAttributeExecutor
{
using SP = std::shared_ptr<IAttributeManager>;
using OnWriteDoneType = const std::shared_ptr<search::IDestructorCallback> &;
diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp
index dac9753773c..908c7e887a3 100644
--- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp
+++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.cpp
@@ -137,7 +137,8 @@ DocsumContext::createSlimeReply()
DocsumContext::DocsumContext(const DocsumRequest & request, IDocsumWriter & docsumWriter,
IDocsumStore & docsumStore, const Matcher::SP & matcher,
ISearchContext & searchCtx, IAttributeContext & attrCtx,
- search::IAttributeManager & attrMgr, SessionManager & sessionMgr) :
+ IAttributeManager & attrMgr, const IAttributeExecutor & attrExec,
+ SessionManager & sessionMgr) :
_request(request),
_docsumWriter(docsumWriter),
_docsumStore(docsumStore),
@@ -145,6 +146,7 @@ DocsumContext::DocsumContext(const DocsumRequest & request, IDocsumWriter & docs
_searchCtx(searchCtx),
_attrCtx(attrCtx),
_attrMgr(attrMgr),
+ _attrExec(attrExec),
_docsumState(*this),
_sessionMgr(sessionMgr)
{
@@ -165,7 +167,7 @@ DocsumContext::FillSummaryFeatures(search::docsummary::GetDocsumsState * state,
{
assert(&_docsumState == state);
if (_matcher->canProduceSummaryFeatures()) {
- state->_summaryFeatures = _matcher->getSummaryFeatures(_request, _searchCtx, _attrCtx, _sessionMgr);
+ state->_summaryFeatures = _matcher->getSummaryFeatures(_request, _searchCtx, _attrCtx, _attrExec, _sessionMgr);
}
state->_summaryFeaturesCached = false;
}
@@ -178,7 +180,7 @@ DocsumContext::FillRankFeatures(search::docsummary::GetDocsumsState * state, sea
if ((state->_args.GetQueryFlags() & search::fs4transport::QFLAG_DUMP_FEATURES) == 0) {
return;
}
- state->_rankFeatures = _matcher->getRankFeatures(_request, _searchCtx, _attrCtx, _sessionMgr);
+ state->_rankFeatures = _matcher->getRankFeatures(_request, _searchCtx, _attrCtx, _attrExec, _sessionMgr);
}
namespace {
diff --git a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h
index 239108ed075..4be67628b1f 100644
--- a/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h
+++ b/searchcore/src/vespa/searchcore/proton/docsummary/docsumcontext.h
@@ -23,6 +23,7 @@ private:
matching::ISearchContext & _searchCtx;
search::attribute::IAttributeContext & _attrCtx;
search::IAttributeManager & _attrMgr;
+ const search::attribute::IAttributeExecutor & _attrExec;
search::docsummary::GetDocsumsState _docsumState;
matching::SessionManager & _sessionMgr;
@@ -40,14 +41,15 @@ public:
matching::ISearchContext & searchCtx,
search::attribute::IAttributeContext & attrCtx,
search::IAttributeManager & attrMgr,
+ const search::attribute::IAttributeExecutor & attrExec,
matching::SessionManager & sessionMgr);
search::engine::DocsumReply::UP getDocsums();
// Implements GetDocsumsStateCallback
- virtual void FillSummaryFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override;
- virtual void FillRankFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override;
- virtual void ParseLocation(search::docsummary::GetDocsumsState * state) override;
+ void FillSummaryFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override;
+ void FillRankFeatures(search::docsummary::GetDocsumsState * state, search::docsummary::IDocsumEnvironment * env) override;
+ void ParseLocation(search::docsummary::GetDocsumsState * state) override;
};
} // namespace proton
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
index 6bce05b6c26..a88a44130f2 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_master.cpp
@@ -4,6 +4,7 @@
#include "docid_range_scheduler.h"
#include "match_loop_communicator.h"
#include "match_thread.h"
+#include <vespa/searchlib/attribute/attribute_operation.h>
#include <vespa/searchlib/common/featureset.h>
#include <vespa/vespalib/util/thread_bundle.h>
@@ -15,6 +16,7 @@ namespace proton::matching {
using namespace search::fef;
using search::queryeval::SearchIterator;
using search::FeatureSet;
+using search::attribute::AttributeOperation;
namespace {
@@ -137,6 +139,10 @@ MatchMaster::getFeatureSet(const MatchToolsFactory &mtf,
LOG(debug, "getFeatureSet: Did not find hit for docid '%u'. Skipping hit", docs[i]);
}
}
+ if (mtf.hasOnReRankOperation()) {
+ mtf.runOnReRankOperation(AttributeOperation::create(mtf.getOnSummaryAttributeType(),
+ mtf.getOnSummaryOperation(), docs));
+ }
return retval;
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp
index 9b5f898495c..2591a176e19 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_thread.cpp
@@ -2,15 +2,17 @@
#include "match_thread.h"
#include "document_scorer.h"
+#include <vespa/searchlib/attribute/attribute_operation.h>
+#include <vespa/searchlib/attribute/i_attribute_functor.h>
+#include <vespa/searchcore/grouping/groupingmanager.h>
+#include <vespa/searchcore/grouping/groupingcontext.h>
+#include <vespa/searchlib/common/bitvector.h>
#include <vespa/searchlib/common/featureset.h>
#include <vespa/searchlib/query/base.h>
#include <vespa/searchlib/queryeval/multibitvectoriterator.h>
#include <vespa/searchlib/queryeval/andnotsearch.h>
#include <vespa/vespalib/util/closure.h>
#include <vespa/vespalib/util/thread_bundle.h>
-#include <vespa/searchcore/grouping/groupingmanager.h>
-#include <vespa/searchcore/grouping/groupingcontext.h>
-#include <vespa/searchlib/common/bitvector.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.matching.match_thread");
@@ -25,6 +27,7 @@ using search::fef::FeatureResolver;
using search::fef::LazyValue;
using search::queryeval::HitCollector;
using search::queryeval::SortedHitSequence;
+using search::attribute::AttributeOperation;
namespace {
@@ -247,8 +250,6 @@ MatchThread::match_loop_helper(MatchTools &tools, HitCollector &hits)
}
}
-//-----------------------------------------------------------------------------
-
search::ResultSet::UP
MatchThread::findMatches(MatchTools &tools)
{
@@ -267,7 +268,8 @@ MatchThread::findMatches(MatchTools &tools)
tools.setup_second_phase();
DocidRange docid_range = scheduler.total_span(thread_id);
tools.search().initRange(docid_range.begin, docid_range.end);
- auto sorted_hit_seq = matchToolsFactory.should_diversify()
+ const MatchToolsFactory & mtf = matchToolsFactory;
+ auto sorted_hit_seq = mtf.should_diversify()
? hits.getSortedHitSequence(matchParams.arraySize)
: hits.getSortedHitSequence(matchParams.heapSize);
WaitTimer select_best_timer(wait_time_s);
@@ -278,6 +280,10 @@ MatchThread::findMatches(MatchTools &tools)
kept_hits.clear();
}
uint32_t reRanked = hits.reRank(scorer, std::move(kept_hits));
+ if (mtf.hasOnReRankOperation()) {
+ mtf.runOnReRankOperation(AttributeOperation::create(mtf.getOnReRankAttributeType(),
+ mtf.getOnReRankOperation(), hits.getReRankedHits()));
+ }
thread_stats.docsReRanked(reRanked);
}
{ // rank scaling
@@ -344,6 +350,11 @@ MatchThread::processResult(const Doom & hardDoom,
}
}
}
+ const MatchToolsFactory & mtf = matchToolsFactory;
+ if (mtf.hasOnMatchOperation() ) {
+ mtf.runOnMatchOperation(AttributeOperation::create(mtf.getOnMatchAttributeType(), mtf.getOnMatchOperation(),
+ search::ResultSet::stealResult(std::move(*result))));
+ }
if (hasGrouping) {
context.grouping->setDistributionKey(_distributionKey);
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp
index 055bc5fe1c2..8b289bd10eb 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.cpp
@@ -16,6 +16,7 @@ using search::attribute::diversity::DiversityFilter;
using namespace search::fef;
using namespace search::fef::indexproperties::matchphase;
using namespace search::fef::indexproperties::matching;
+using namespace search::fef::indexproperties;
using search::IDocumentMetaStore;
namespace proton::matching {
@@ -150,6 +151,7 @@ MatchToolsFactory(QueryLimiter & queryLimiter,
vespalib::stringref queryStack,
const vespalib::string & location,
const ViewResolver & viewResolver,
+ const IAttributeExecutor & attrExec,
const IDocumentMetaStore & metaStore,
const IIndexEnvironment & indexEnv,
const RankSetup & rankSetup,
@@ -162,6 +164,7 @@ MatchToolsFactory(QueryLimiter & queryLimiter,
_match_limiter(),
_queryEnv(indexEnv, attributeContext, rankProperties),
_mdl(),
+ _attrExec(attrExec),
_rankSetup(rankSetup),
_featureOverrides(featureOverrides),
_diversityParams(),
@@ -199,7 +202,8 @@ MatchToolsFactory::createMatchTools() const
*_match_limiter, _queryEnv, _mdl, _rankSetup, _featureOverrides);
}
-std::unique_ptr<IDiversifier> MatchToolsFactory::createDiversifier() const
+std::unique_ptr<IDiversifier>
+MatchToolsFactory::createDiversifier() const
{
if ( !_diversityParams.enabled() ) {
return std::unique_ptr<IDiversifier>();
@@ -214,4 +218,70 @@ std::unique_ptr<IDiversifier> MatchToolsFactory::createDiversifier() const
_diversityParams.cutoff_strategy == DiversityParams::CutoffStrategy::STRICT);
}
+bool
+MatchToolsFactory::hasOnMatchOperation() const {
+ return ! execute::onmatch::Attribute::lookup(_queryEnv.getProperties()).empty() &&
+ ! execute::onmatch::Operation::lookup(_queryEnv.getProperties()).empty();
+}
+
+vespalib::string
+MatchToolsFactory::getOnMatchOperation() const {
+ return execute::onmatch::Operation::lookup(_queryEnv.getProperties());
+}
+
+void
+MatchToolsFactory::runOnMatchOperation(std::shared_ptr<IAttributeFunctor> count) const {
+ _attrExec.asyncForAttribute(execute::onmatch::Attribute::lookup(_queryEnv.getProperties()), std::move(count));
+}
+
+search::attribute::BasicType
+MatchToolsFactory::getOnMatchAttributeType() const {
+ auto attr = _requestContext.getAttribute(execute::onmatch::Attribute::lookup(_queryEnv.getProperties()));
+ return attr ? attr->getBasicType() : BasicType::NONE;
+}
+
+bool
+MatchToolsFactory::hasOnReRankOperation() const {
+ return ! execute::onrerank::Attribute::lookup(_queryEnv.getProperties()).empty() &&
+ ! execute::onrerank::Operation::lookup(_queryEnv.getProperties()).empty();
+}
+
+vespalib::string
+MatchToolsFactory::getOnReRankOperation() const {
+ return execute::onrerank::Operation::lookup(_queryEnv.getProperties());
+}
+
+void
+MatchToolsFactory::runOnReRankOperation(std::shared_ptr<IAttributeFunctor> count) const {
+ _attrExec.asyncForAttribute(execute::onrerank::Attribute::lookup(_queryEnv.getProperties()), std::move(count));
+}
+
+search::attribute::BasicType
+MatchToolsFactory::getOnReRankAttributeType() const {
+ auto attr = _requestContext.getAttribute(execute::onrerank::Attribute::lookup(_queryEnv.getProperties()));
+ return attr ? attr->getBasicType() : BasicType::NONE;
+}
+
+bool
+MatchToolsFactory::hasOnSummaryOperation() const {
+ return ! execute::onsummary::Attribute::lookup(_queryEnv.getProperties()).empty() &&
+ ! execute::onsummary::Operation::lookup(_queryEnv.getProperties()).empty();
+}
+
+vespalib::string
+MatchToolsFactory::getOnSummaryOperation() const {
+ return execute::onsummary::Operation::lookup(_queryEnv.getProperties());
+}
+
+void
+MatchToolsFactory::runOnSummaryOperation(std::shared_ptr<IAttributeFunctor> count) const {
+ _attrExec.asyncForAttribute(execute::onsummary::Attribute::lookup(_queryEnv.getProperties()), std::move(count));
+}
+
+search::attribute::BasicType
+MatchToolsFactory::getOnSummaryAttributeType() const {
+ auto attr = _requestContext.getAttribute(execute::onsummary::Attribute::lookup(_queryEnv.getProperties()));
+ return attr ? attr->getBasicType() : BasicType::NONE;
+}
+
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h
index 314dfc64a9d..9a28dc1ed05 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/match_tools.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/match_tools.h
@@ -6,18 +6,17 @@
#include "isearchcontext.h"
#include "query.h"
#include "viewresolver.h"
-#include <vespa/vespalib/util/doom.h>
#include "querylimiter.h"
#include "match_phase_limiter.h"
#include "handlerecorder.h"
#include "requestcontext.h"
-
-#include <vespa/vespalib/util/clock.h>
+#include <vespa/searchlib/attribute/i_attribute_functor.h>
#include <vespa/searchlib/queryeval/blueprint.h>
#include <vespa/searchlib/fef/fef.h>
#include <vespa/searchlib/common/idocumentmetastore.h>
#include <vespa/searchlib/queryeval/idiversifier.h>
-
+#include <vespa/vespalib/util/doom.h>
+#include <vespa/vespalib/util/clock.h>
namespace proton::matching {
@@ -73,6 +72,8 @@ public:
class MatchToolsFactory : public vespalib::noncopyable
{
private:
+ using IAttributeExecutor = search::attribute::IAttributeExecutor;
+ using IAttributeFunctor = search::attribute::IAttributeFunctor;
QueryLimiter & _queryLimiter;
RequestContext _requestContext;
const vespalib::Doom _hardDoom;
@@ -80,12 +81,14 @@ private:
MaybeMatchPhaseLimiter::UP _match_limiter;
QueryEnvironment _queryEnv;
search::fef::MatchDataLayout _mdl;
+ const IAttributeExecutor & _attrExec;
const search::fef::RankSetup & _rankSetup;
const search::fef::Properties & _featureOverrides;
DiversityParams _diversityParams;
bool _valid;
public:
- typedef std::unique_ptr<MatchToolsFactory> UP;
+ using UP = std::unique_ptr<MatchToolsFactory>;
+ using BasicType = search::attribute::BasicType;
MatchToolsFactory(QueryLimiter & queryLimiter,
const vespalib::Doom & softDoom,
@@ -95,6 +98,7 @@ public:
vespalib::stringref queryStack,
const vespalib::string &location,
const ViewResolver &viewResolver,
+ const IAttributeExecutor & attrExec,
const search::IDocumentMetaStore &metaStore,
const search::fef::IIndexEnvironment &indexEnv,
const search::fef::RankSetup &rankSetup,
@@ -108,6 +112,19 @@ public:
std::unique_ptr<search::queryeval::IDiversifier> createDiversifier() const;
search::queryeval::Blueprint::HitEstimate estimate() const { return _query.estimate(); }
bool has_first_phase_rank() const { return !_rankSetup.getFirstPhaseRank().empty(); }
+ bool hasOnMatchOperation() const;
+ BasicType getOnMatchAttributeType() const;
+ vespalib::string getOnMatchOperation() const;
+ void runOnMatchOperation(std::shared_ptr<IAttributeFunctor> count) const;
+ bool hasOnReRankOperation() const;
+ BasicType getOnReRankAttributeType() const;
+ vespalib::string getOnReRankOperation() const;
+ void runOnReRankOperation(std::shared_ptr<IAttributeFunctor> count) const;
+ bool hasOnSummaryOperation() const;
+ BasicType getOnSummaryAttributeType() const;
+ vespalib::string getOnSummaryOperation() const;
+ void runOnSummaryOperation(std::shared_ptr<IAttributeFunctor> count) const;
+ const RequestContext & requestContext() const { return _requestContext; }
};
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp
index bce13a96da7..c387d3ea4eb 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.cpp
@@ -95,7 +95,7 @@ bool willNotNeedRanking(const SearchRequest & request, const GroupingContext & g
FeatureSet::SP
Matcher::getFeatureSet(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx,
- SessionManager & sessionMgr, bool summaryFeatures)
+ const IAttributeExecutor & attrExec, SessionManager & sessionMgr, bool summaryFeatures)
{
SessionId sessionId(&req.sessionId[0], req.sessionId.size());
if (!sessionId.empty()) {
@@ -113,7 +113,7 @@ Matcher::getFeatureSet(const DocsumRequest & req, ISearchContext & searchCtx, IA
}
StupidMetaStore metaStore;
- MatchToolsFactory::UP mtf = create_match_tools_factory(req, searchCtx, attrCtx, metaStore,
+ MatchToolsFactory::UP mtf = create_match_tools_factory(req, searchCtx, attrCtx, attrExec, metaStore,
req.propertiesMap.featureOverrides());
if (!mtf->valid()) {
LOG(warning, "getFeatureSet(%s): query execution failed (invalid query). Returning empty feature set",
@@ -159,8 +159,8 @@ using search::fef::indexproperties::softtimeout::Factor;
std::unique_ptr<MatchToolsFactory>
Matcher::create_match_tools_factory(const search::engine::Request &request, ISearchContext &searchContext,
- IAttributeContext &attrContext, const search::IDocumentMetaStore &metaStore,
- const Properties &feature_overrides) const
+ IAttributeContext &attrContext, const IAttributeExecutor & attrExec,
+ const search::IDocumentMetaStore &metaStore, const Properties &feature_overrides) const
{
const Properties & rankProperties = request.propertiesMap.rankProperties();
bool softTimeoutEnabled = Enabled::lookup(rankProperties, _rankSetup->getSoftTimeoutEnabled());
@@ -176,7 +176,8 @@ Matcher::create_match_tools_factory(const search::engine::Request &request, ISea
return std::make_unique<MatchToolsFactory>(_queryLimiter, vespalib::Doom(_clock, safeDoom),
vespalib::Doom(_clock, request.getTimeOfDoom()), searchContext,
attrContext, request.getStackRef(), request.location, _viewResolver,
- metaStore, _indexEnv, *_rankSetup, rankProperties, feature_overrides);
+ attrExec, metaStore, _indexEnv, *_rankSetup,
+ rankProperties, feature_overrides);
}
SearchReply::UP
@@ -205,8 +206,8 @@ Matcher::computeNumThreadsPerSearch(Blueprint::HitEstimate hits, const Propertie
SearchReply::UP
Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundle,
ISearchContext &searchContext, IAttributeContext &attrContext,
- SessionManager &sessionMgr, const search::IDocumentMetaStore &metaStore,
- SearchSession::OwnershipBundle &&owned_objects)
+ const IAttributeExecutor & attrExec, SessionManager &sessionMgr,
+ const search::IDocumentMetaStore &metaStore, SearchSession::OwnershipBundle &&owned_objects)
{
fastos::StopWatch total_matching_time;
total_matching_time.start();
@@ -236,7 +237,7 @@ Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundl
feature_overrides = owned_objects.feature_overrides.get();
}
MatchToolsFactory::UP mtf = create_match_tools_factory(request, searchContext, attrContext,
- metaStore, *feature_overrides);
+ attrExec, metaStore, *feature_overrides);
if (!mtf->valid()) {
reply->errorCode = ECODE_QUERY_PARSE_ERROR;
reply->errorMessage = "query execution failed (invalid query)";
@@ -325,17 +326,17 @@ Matcher::match(const SearchRequest &request, vespalib::ThreadBundle &threadBundl
}
FeatureSet::SP
-Matcher::getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx,
- IAttributeContext & attrCtx, SessionManager &sessionMgr)
+Matcher::getSummaryFeatures(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx,
+ const IAttributeExecutor & attrExec, SessionManager &sessionMgr)
{
- return getFeatureSet(req, searchCtx, attrCtx, sessionMgr, true);
+ return getFeatureSet(req, searchCtx, attrCtx, attrExec, sessionMgr, true);
}
FeatureSet::SP
-Matcher::getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx,
- IAttributeContext & attrCtx, SessionManager &sessionMgr)
+Matcher::getRankFeatures(const DocsumRequest & req, ISearchContext & searchCtx, IAttributeContext & attrCtx,
+ const IAttributeExecutor & attrExec, SessionManager &sessionMgr)
{
- return getFeatureSet(req, searchCtx, attrCtx, sessionMgr, false);
+ return getFeatureSet(req, searchCtx, attrCtx, attrExec, sessionMgr, false);
}
}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/matcher.h b/searchcore/src/vespa/searchcore/proton/matching/matcher.h
index 4786e9f7f7c..15df21378d2 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/matcher.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/matcher.h
@@ -8,6 +8,7 @@
#include "search_session.h"
#include "viewresolver.h"
#include <vespa/searchcore/proton/matching/querylimiter.h>
+#include <vespa/searchlib/attribute/i_attribute_functor.h>
#include <vespa/searchlib/common/featureset.h>
#include <vespa/searchlib/common/resultset.h>
#include <vespa/searchlib/queryeval/blueprint.h>
@@ -44,6 +45,7 @@ class MatchToolsFactory;
class Matcher
{
private:
+ using IAttributeExecutor = search::attribute::IAttributeExecutor;
IndexEnvironment _indexEnv;
search::fef::BlueprintFactory _blueprintFactory;
search::fef::RankSetup::SP _rankSetup;
@@ -57,7 +59,7 @@ private:
search::FeatureSet::SP
getFeatureSet(const search::engine::DocsumRequest & req, ISearchContext & searchCtx,
search::attribute::IAttributeContext & attrCtx,
- SessionManager &sessionMgr, bool summaryFeatures);
+ const IAttributeExecutor & attrExec, SessionManager &sessionMgr, bool summaryFeatures);
std::unique_ptr<search::engine::SearchReply>
handleGroupingSession(SessionManager &sessionMgr,
search::grouping::GroupingContext & groupingContext,
@@ -69,7 +71,6 @@ public:
/**
* Convenience typedefs.
*/
- typedef std::unique_ptr<Matcher> UP;
typedef std::shared_ptr<Matcher> SP;
@@ -104,6 +105,7 @@ public:
std::unique_ptr<MatchToolsFactory>
create_match_tools_factory(const search::engine::Request &request, ISearchContext &searchContext,
search::attribute::IAttributeContext &attrContext,
+ const IAttributeExecutor & attrExec,
const search::IDocumentMetaStore &metaStore,
const search::fef::Properties &feature_overrides) const;
@@ -121,7 +123,7 @@ public:
std::unique_ptr<search::engine::SearchReply>
match(const search::engine::SearchRequest &request, vespalib::ThreadBundle &threadBundle,
ISearchContext &searchContext, search::attribute::IAttributeContext &attrContext,
- SessionManager &sessionManager, const search::IDocumentMetaStore &metaStore,
+ const IAttributeExecutor & attrExec, SessionManager &sessionManager, const search::IDocumentMetaStore &metaStore,
SearchSession::OwnershipBundle &&owned_objects);
/**
@@ -136,7 +138,8 @@ public:
**/
search::FeatureSet::SP
getSummaryFeatures(const search::engine::DocsumRequest & req, ISearchContext & searchCtx,
- search::attribute::IAttributeContext & attrCtx, SessionManager &sessionManager);
+ search::attribute::IAttributeContext & attrCtx,
+ const IAttributeExecutor & attrExec, SessionManager &sessionManager);
/**
* Perform matching for the documents in the given docsum request
@@ -150,7 +153,8 @@ public:
**/
search::FeatureSet::SP
getRankFeatures(const search::engine::DocsumRequest & req, ISearchContext & searchCtx,
- search::attribute::IAttributeContext & attrCtx, SessionManager &sessionManager);
+ search::attribute::IAttributeContext & attrCtx,
+ const IAttributeExecutor & attrExec, SessionManager &sessionManager);
/**
* @return true if this rankprofile has summary-features enabled
diff --git a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp
index 9af648917c4..ab9a4b93b5f 100644
--- a/searchcore/src/vespa/searchcore/proton/server/matchview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/matchview.cpp
@@ -77,7 +77,7 @@ MatchView::match(const ISearchHandler::SP &searchHandler, const SearchRequest &r
MatchContext *ctx = owned_objects.context.get();
const search::IDocumentMetaStore & dms = owned_objects.readGuard->get();
return matcher->match(req, threadBundle, ctx->getSearchContext(), ctx->getAttributeContext(),
- *_sessionMgr, dms, std::move(owned_objects));
+ *_attrMgr, *_sessionMgr, dms, std::move(owned_objects));
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp
index 232f0bdba6c..6879e106c5e 100644
--- a/searchcore/src/vespa/searchcore/proton/server/searchview.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/searchview.cpp
@@ -147,9 +147,10 @@ SearchView::getDocsumsInternal(const DocsumRequest & req)
IDocsumStore::UP store(_summarySetup->createDocsumStore(req.resultClassName));
Matcher::SP matcher = _matchView->getMatcher(req.ranking);
MatchContext::UP mctx = _matchView->createContext();
- DocsumContext::UP ctx(new DocsumContext(req, _summarySetup->getDocsumWriter(), *store, matcher,
- mctx->getSearchContext(), mctx->getAttributeContext(),
- *_summarySetup->getAttributeManager(), *getSessionManager()));
+ auto ctx = std::make_unique<DocsumContext>(req, _summarySetup->getDocsumWriter(), *store, matcher,
+ mctx->getSearchContext(), mctx->getAttributeContext(),
+ *_summarySetup->getAttributeManager(), *_matchView->getAttributeManager(),
+ *getSessionManager());
SearchView::InternalDocsumReply reply(ctx->getDocsums(), true);
uint64_t endGeneration = readGuard->get().getCurrentGeneration();
if (startGeneration != endGeneration) {
diff --git a/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h b/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h
index 4ad3aa5fb42..9fc019a2ded 100644
--- a/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h
+++ b/searchcore/src/vespa/searchcore/proton/test/mock_attribute_manager.h
@@ -75,6 +75,7 @@ public:
const ImportedAttributesRepo *getImportedAttributes() const override {
return _importedAttributes.get();
}
+ void asyncForAttribute(const vespalib::string &, std::shared_ptr<IAttributeFunctor>) const override { }
};
}