elasticsearch_dsl/search/queries/compound/
boosting_query.rs

1use crate::search::*;
2use crate::util::*;
3
4/// Returns documents matching a `positive` query while reducing the
5/// [relevance score](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html#relevance-scores)
6/// of documents that also match a `negative` query.
7///
8/// You can use the `boosting` query to demote certain documents without excluding them from the search results.
9///
10/// To create boosting query:
11/// ```
12/// # use elasticsearch_dsl::queries::*;
13/// # use elasticsearch_dsl::queries::params::*;
14/// # let query =
15/// Query::boosting(Query::term("test1", 123), Query::term("test2", 456), 0.2)
16///    .boost(3)
17///    .name("test");
18/// ```
19/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html>
20#[derive(Debug, Clone, PartialEq, Serialize)]
21#[serde(remote = "Self")]
22pub struct BoostingQuery {
23    positive: Box<Query>,
24
25    negative: Box<Query>,
26
27    negative_boost: NegativeBoost,
28
29    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
30    boost: Option<f32>,
31
32    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
33    _name: Option<String>,
34}
35
36impl Query {
37    /// Creates an instance of [`BoostingQuery`]
38    ///
39    /// - `positive` - Query you wish to run. Any returned documents must match this query.
40    /// - `negative` - Query used to decrease the
41    ///   [relevance score](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html#relevance-scores)
42    ///   of matching documents.<br/>
43    ///   If a returned document matches the `positive` query and this query, the `boosting` query
44    ///   calculates the final
45    ///   [relevance score](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html#relevance-scores)
46    ///   for the document as follows:
47    ///     1. Take the original relevance score from the `positive` query.
48    ///     2. Multiply the score by the `negative_boost` value.
49    /// - `negative_boost` - Floating point number between `0` and `1.0` used to decrease the
50    ///   [relevance scores](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html#relevance-scores)
51    ///   of documents matching the `negative` query.
52    pub fn boosting<Q, B>(positive: Q, negative: Q, negative_boost: B) -> BoostingQuery
53    where
54        Q: Into<Query>,
55        B: Into<NegativeBoost>,
56    {
57        BoostingQuery {
58            positive: Box::new(positive.into()),
59            negative: Box::new(negative.into()),
60            negative_boost: negative_boost.into(),
61            boost: None,
62            _name: None,
63        }
64    }
65}
66
67impl BoostingQuery {
68    add_boost_and_name!();
69}
70
71impl ShouldSkip for BoostingQuery {
72    fn should_skip(&self) -> bool {
73        self.positive.should_skip() || self.negative.should_skip()
74    }
75}
76
77serialize_with_root!("boosting": BoostingQuery);
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn serialization() {
85        assert_serialize_query(
86            Query::boosting(Query::term("test1", 123), Query::term("test2", 456), 0.2),
87            json!({
88                "boosting": {
89                    "positive": {
90                        "term": {
91                            "test1": {
92                                "value": 123
93                            }
94                        }
95                    },
96                    "negative": {
97                        "term": {
98                            "test2": {
99                                "value": 456
100                            }
101                        }
102                    },
103                    "negative_boost": 0.2
104                }
105            }),
106        );
107
108        assert_serialize_query(
109            Query::boosting(Query::term("test1", 123), Query::term("test2", 456), 0.2)
110                .boost(3)
111                .name("test"),
112            json!({
113                "boosting": {
114                    "positive": {
115                        "term": {
116                            "test1": {
117                                "value": 123
118                            }
119                        }
120                    },
121                    "negative": {
122                        "term": {
123                            "test2": {
124                                "value": 456
125                            }
126                        }
127                    },
128                    "negative_boost": 0.2,
129                    "boost": 3.0,
130                    "_name": "test"
131                }
132            }),
133        );
134    }
135}