aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/prelude/query/WandItem.java
blob: 8aef14a11b86d17cc270df8001eb95bfffd20d02 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;

import com.yahoo.compress.IntegerCompressor;
import com.yahoo.prelude.query.textualrepresentation.Discloser;

import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Objects;

/**
 * A weighted set query item to be evaluated as a Wand with dot product scoring.
 *
 * The dot product is calculated between the matched tokens of the weighted set field searched
 * and the weights associated with the tokens of this WandItem.
 * The resulting dot product will be available as a raw score in the rank framework.
 *
 * @author geirst
 */
public class WandItem extends WeightedSetItem {

    private final int targetNumHits;
    private double scoreThreshold = 0;
    private double thresholdBoostFactor = 1;

    /**
     * Creates an empty WandItem.
     *
     * @param fieldName the name of the weighted set field to search with this WandItem.
     * @param targetNumHits the target for minimum number of hits to produce by the backend search operator handling this WandItem.
     */
    public WandItem(String fieldName, int targetNumHits) {
        super(fieldName);
        this.targetNumHits = targetNumHits;
    }

    /**
     * Creates an empty WandItem.
     *
     * @param fieldName the name of the weighted set field to search with this WandItem.
     * @param targetNumHits the target for minimum number of hits to produce by the backend search operator handling this WandItem.
     * @param tokens the tokens to search for
     */
    public WandItem(String fieldName, int targetNumHits, Map<Object, Integer> tokens) {
        super(fieldName, tokens);
        this.targetNumHits = targetNumHits;
    }

    /**
     * Sets the initial score threshold used by the backend search operator handling this WandItem.
     * The score of a document must be larger than this threshold in order to be considered a match.
     * Default value is 0.0.
     *
     * @param scoreThreshold the initial score threshold.
     */
    public void setScoreThreshold(double scoreThreshold) {
        this.scoreThreshold = scoreThreshold;
    }

    /**
     * Sets the boost factor used by the backend search operator to boost the threshold before
     * comparing it with the upper bound score of the document being evaluated.
     * A large value of this factor results in fewer full evaluations and in an expected loss in precision.
     * Similarly, a gain in performance might be expected. Default value is 1.0.
     *
     * NOTE: This boost factor is only used when this WandItem is searching a Vespa field.
     *
     * @param thresholdBoostFactor the boost factor.
     */
    public void setThresholdBoostFactor(double thresholdBoostFactor) {
        this.thresholdBoostFactor = thresholdBoostFactor;
    }

    public int getTargetNumHits() {
        return targetNumHits;
    }

    public double getScoreThreshold() {
        return scoreThreshold;
    }

    public double getThresholdBoostFactor() {
        return thresholdBoostFactor;
    }

    @Override
    public ItemType getItemType() {
        return ItemType.WAND;
    }

    @Override
    protected void encodeThis(ByteBuffer buffer) {
        super.encodeThis(buffer);
        IntegerCompressor.putCompressedPositiveNumber(targetNumHits, buffer);
        buffer.putDouble(scoreThreshold);
        buffer.putDouble(thresholdBoostFactor);
    }

    @Override
    protected void appendHeadingString(StringBuilder buffer) {
        buffer.append(getName());
        buffer.append("(");
        buffer.append(targetNumHits).append(",");
        buffer.append(scoreThreshold).append(",");
        buffer.append(thresholdBoostFactor);
        buffer.append(") ");
    }

    @Override
    public void disclose(Discloser discloser) {
        super.disclose(discloser);
        discloser.addProperty("targetNumHits", targetNumHits);
        discloser.addProperty("scoreThreshold", scoreThreshold);
        discloser.addProperty("thresholdBoostFactor", thresholdBoostFactor);
    }

    @Override
    public boolean equals(Object o) {
        if ( ! super.equals(o)) return false;
        var other = (WandItem)o;
        if ( this.targetNumHits != other.targetNumHits) return false;
        if ( this.scoreThreshold != other.scoreThreshold) return false;
        if ( this.thresholdBoostFactor != other.thresholdBoostFactor) return false;
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), targetNumHits, scoreThreshold, thresholdBoostFactor);
    }

}