Skip to main content

qdrant_edge/edge/
facet.rs

1use std::collections::HashMap;
2use std::sync::atomic::AtomicBool;
3
4use crate::common::counter::hardware_accumulator::HwMeasurementAcc;
5use crate::segment::common::operation_error::OperationResult;
6use crate::segment::data_types::facets::{FacetParams, FacetResponse};
7use crate::shard::facet::FacetRequestInternal;
8
9use super::EdgeShard;
10
11impl EdgeShard {
12    /// Returns facet hits for the given facet request.
13    ///
14    /// Counts the number of points for each unique value of the specified payload key,
15    /// optionally filtering by the given conditions.
16    pub fn facet(&self, request: FacetRequestInternal) -> OperationResult<FacetResponse> {
17        let FacetRequestInternal {
18            key,
19            limit,
20            filter,
21            exact,
22        } = request;
23
24        let (non_appendable, appendable) = self.segments.read().split_segments();
25        let segments = non_appendable.into_iter().chain(appendable);
26
27        let hw_counter = HwMeasurementAcc::disposable_edge().get_counter_cell();
28        let is_stopped = AtomicBool::new(false);
29
30        let facet_params = FacetParams {
31            key,
32            limit,
33            filter,
34            exact,
35        };
36
37        // Collect and merge facet results from all segments
38        let mut merged_counts = HashMap::new();
39        for segment in segments {
40            let segment_result =
41                segment
42                    .get()
43                    .read()
44                    .facet(&facet_params, &is_stopped, &hw_counter)?;
45
46            for (value, count) in segment_result {
47                *merged_counts.entry(value).or_insert(0) += count;
48            }
49        }
50
51        Ok(FacetResponse::top_hits(merged_counts, limit))
52    }
53}