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
//! Top-K Collectors, with ordering and condition support. //! //! This is a collection of collectors that provide top docs //! rank functionality very similar to `tantivy::TopDocs`, with //! added support for declaring the ordering (ascending or //! descending) and collection-time conditions. //! //! ```rust //! # use tique::conditional_collector::{Descending,TopCollector}; //! # use tantivy::Score; //! # let condition_for_segment = true; //! let collector = //! TopCollector::<Score, Descending, _>::new(10, condition_for_segment); //! ``` //! //! NOTE: Usually the score type (`Score` above, a `f32`) is inferred //! so there's no need to specify it. //! //! # Ordering Support //! //! When constructing a top collector you *must* specify how to //! actually order the items: in ascending or descending order. //! //! You simply choose `Ascending` or `Descending` and let the //! compiler know: //! //! ```rust //! # use tique::conditional_collector::{Ascending,TopCollector}; //! # use tantivy::Score; //! # let limit = 10; //! # let condition_for_segment = true; //! let collector = //! TopCollector::<Score, Ascending, _>::new(limit, condition_for_segment); //! ``` //! //! # Condition Support //! //! A "condition" is simply a way to tell the collector that //! a document is a valid candidate to the top. It behaves //! just like a query filter would, but does not limit the //! candidates before the collector sees them. //! //! This is a valid condition that accepts everything: //! //! ```rust //! let condition_for_segment = true; //! ``` //! //! Generally speaking, a `condition` is anything that implements //! the `ConditionForSegment` trait and you can use closures as a //! shortcut: //! //! ```rust //! # use tantivy::{Score,SegmentReader}; //! # use tique::conditional_collector::{TopCollector,Ascending}; //! # let limit = 10; //! let condition_for_segment = move |reader: &SegmentReader| { //! // Fetch useful stuff from the `reader`, then: //! move |segment_id, doc_id, score, is_ascending| { //! // Express whatever logic you want //! true //! } //! }; //! //! let collector = //! TopCollector::<Score, Ascending, _>::new(limit, condition_for_segment); //! ``` //! //! ## Aside: Pagination with Constant Memory //! //! If you've been using `tantivy` for a while, you're probably //! used to seeing tuples like `(T, DocAddress)` (T is usually //! `tantivy::Score`, but changes if you customize the score //! somehow). //! //! You can also use these tuples as a condition and they act //! like a cursor for pagination, so when you do something like: //! //! ```rust //! # use tantivy::DocAddress; //! # use tique::conditional_collector::{TopCollector,Descending}; //! let limit = 10; //! let condition_for_segment = (0.42, DocAddress(0, 1)); //! let collector = //! TopCollector::<_, Descending, _>::new(limit, condition_for_segment); //! ``` //! //! What you are asking for is the top `limit` documents that appear //! *after* (because you chose the `Descending` order) documents //! that scored `0.42` at whatever query you throw at it (and in //! case multiple docs score the name, the collector knows to //! break even by the `DocAddress`). //! //! The results that you get after your search will contain more //! `(T, DocAddress)` tuples you can use to keep pagination //! going without ever having to increase `limit`. //! //! Check `examples/conditional_collector_tutorial.rs` for more details. mod custom_score; mod top_collector; pub(crate) mod topk; mod traits; pub use top_collector::{CollectionResult, TopCollector}; pub use topk::{Ascending, Descending}; pub use traits::*;