// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once #include #include #include "params.h" namespace search::features::fieldmatch { /** * The collection of simple metrics calculated when traversing the query terms of the query environment. **/ class SimpleMetrics { private: const Params & _params; uint32_t _matches; uint32_t _matchesWithPosOcc; bool _matchWithInvalidFieldLength; // 0 or UNKNOWN_LENGTH uint32_t _numTerms; uint32_t _matchedWeight; uint32_t _totalWeightInField; uint32_t _totalWeightInQuery; public: /** * Constructs a new object. **/ SimpleMetrics(const Params & params); /** * Resets the match data of this object. **/ void resetMatchData() { _matches = 0; _matchesWithPosOcc = 0; _matchWithInvalidFieldLength = false; _matchedWeight = 0; } /** * Registers a match in the field in question. * * @param weight The weight of the term matching. **/ void addMatch(uint32_t weight) { ++_matches; _matchedWeight += weight; } /** * Registers a match in the field in question. * We have position information for this term match. * * @param weight The weight of the term matching. **/ void addMatchWithPosOcc(uint32_t weight) { addMatch(weight); ++_matchesWithPosOcc; } /** * Registers that a match has invalid field length. **/ void hasMatchWithInvalidFieldLength() { _matchWithInvalidFieldLength = true; } /** * Registers a term that is searching in the field in question. * * @param weight The weight of the term. **/ void addSearchedTerm(uint32_t weight) { ++_numTerms; _totalWeightInField += weight; } /** * Registers a query term with the given weight. * * @param weight The weight of the term. **/ void addQueryTerm(uint32_t weight) { _totalWeightInQuery += weight; } /** * Overrides the total weight for all query terms. * * @param weight The total weight. **/ void setTotalWeightInQuery(uint32_t weight) { _totalWeightInQuery = weight; } /** * Returns the normalized score for this object. * total weight of matched terms in the field / total weight of searched terms in the field * * @return The score. **/ feature_t getScore() const { return _totalWeightInField > 0 ? _matchedWeight / static_cast(_totalWeightInField) : 0; } /** * Returns the completeness score for this object. * queryCompleteness * ( 1 - fieldCompletenessImportance ) * * @return The completeness. **/ feature_t getCompleteness() const { return getQueryCompleteness() * (1 - _params.getFieldCompletenessImportance()); } /** * Returns the query completeness score for this object. * total number of matched terms in the field / total number of searched terms in the field * * @return The query completeness. **/ feature_t getQueryCompleteness() const { return _numTerms > 0 ? _matches / static_cast(_numTerms) : 0; } /** * Returns the weight score for this object. * total weight of matched terms in the field / total weight of all query terms * * @return The weight. **/ feature_t getWeight() const { return _totalWeightInQuery > 0 ? _matchedWeight / static_cast(_totalWeightInQuery) : 0; } /** * Returns the number of matches in the field in question. * * @return The number of matches. **/ uint32_t getMatches() const { return _matches; } /** * Returns the number of matches in the field in question with position information. * * @return The number of matches with position information. **/ uint32_t getMatchesWithPosOcc() const { return _matchesWithPosOcc; } /** * Returns the number of degraded matches (no position information) in the field in question. * * @return The number of degraded matches. **/ uint32_t getDegradedMatches() const { return getMatches() - getMatchesWithPosOcc(); } /** * Returns whether we have a match in the field in question with invalid field length. * * @return Whether we have seen an invalid field length. **/ bool getMatchWithInvalidFieldLength() const { return _matchWithInvalidFieldLength; } /** * Returns a string representation of this object. * * @return String representation. **/ vespalib::string toString() const; }; }