mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 12:05:05 +08:00
feat: Introduce the SortBy help structure
This structure help ranking documents using stored attributes.
This commit is contained in:
parent
23cce69dc5
commit
d615f89c56
19
src/rank/criterion/document_id.rs
Normal file
19
src/rank/criterion/document_id.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
|
|
||||||
|
use crate::rank::criterion::Criterion;
|
||||||
|
use crate::database::DatabaseView;
|
||||||
|
use crate::rank::Document;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct DocumentId;
|
||||||
|
|
||||||
|
impl<D> Criterion<D> for DocumentId
|
||||||
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
|
lhs.id.cmp(&rhs.id)
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,9 @@ mod exact;
|
|||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::marker;
|
||||||
|
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
use rocksdb::DB;
|
use rocksdb::DB;
|
||||||
|
|
||||||
use crate::database::DatabaseView;
|
use crate::database::DatabaseView;
|
||||||
@ -69,6 +71,73 @@ where D: Deref<Target=DB>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An helper struct that permit to sort documents by
|
||||||
|
/// some of their stored attributes.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// If a document cannot be deserialized it will be considered [`None`][].
|
||||||
|
///
|
||||||
|
/// Deserialized documents are compared like `Some(doc0).cmp(&Some(doc1))`,
|
||||||
|
/// so you must check the [`Ord`] of `Option` implementation.
|
||||||
|
///
|
||||||
|
/// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
|
||||||
|
/// [`Ord`]: https://doc.rust-lang.org/std/option/enum.Option.html#impl-Ord
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use serde_derive::Deserialize;
|
||||||
|
/// use meilidb::rank::criterion::*;
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
|
/// struct TimeOnly {
|
||||||
|
/// time: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let builder = CriteriaBuilder::with_capacity(7)
|
||||||
|
/// .add(SumOfTypos)
|
||||||
|
/// .add(NumberOfWords)
|
||||||
|
/// .add(WordsProximity)
|
||||||
|
/// .add(SumOfWordsAttribute)
|
||||||
|
/// .add(SumOfWordsPosition)
|
||||||
|
/// .add(Exact)
|
||||||
|
/// .add(SortBy::<TimeOnly>::new())
|
||||||
|
/// .add(DocumentId);
|
||||||
|
///
|
||||||
|
/// let criterion = builder.build();
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SortBy<T> {
|
||||||
|
_phantom: marker::PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SortBy<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
SortBy { _phantom: marker::PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, D> Criterion<D> for SortBy<T>
|
||||||
|
where D: Deref<Target=DB>,
|
||||||
|
T: DeserializeOwned + Ord,
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> Ordering {
|
||||||
|
let lhs = match view.retrieve_document::<T>(lhs.id) {
|
||||||
|
Ok(doc) => Some(doc),
|
||||||
|
Err(e) => { eprintln!("{}", e); None },
|
||||||
|
};
|
||||||
|
|
||||||
|
let rhs = match view.retrieve_document::<T>(rhs.id) {
|
||||||
|
Ok(doc) => Some(doc),
|
||||||
|
Err(e) => { eprintln!("{}", e); None },
|
||||||
|
};
|
||||||
|
|
||||||
|
lhs.cmp(&rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CriteriaBuilder<D>
|
pub struct CriteriaBuilder<D>
|
||||||
where D: Deref<Target=DB>
|
where D: Deref<Target=DB>
|
||||||
{
|
{
|
||||||
|
77
src/rank/criterion/sort_by.rs
Normal file
77
src/rank/criterion/sort_by.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::marker;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
|
use crate::rank::criterion::Criterion;
|
||||||
|
use crate::database::DatabaseView;
|
||||||
|
use crate::rank::Document;
|
||||||
|
|
||||||
|
/// An helper struct that permit to sort documents by
|
||||||
|
/// some of their stored attributes.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// If a document cannot be deserialized it will be considered [`None`][].
|
||||||
|
///
|
||||||
|
/// Deserialized documents are compared like `Some(doc0).cmp(&Some(doc1))`,
|
||||||
|
/// so you must check the [`Ord`] of `Option` implementation.
|
||||||
|
///
|
||||||
|
/// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
|
||||||
|
/// [`Ord`]: https://doc.rust-lang.org/std/option/enum.Option.html#impl-Ord
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```no-test
|
||||||
|
/// use serde_derive::Deserialize;
|
||||||
|
/// use meilidb::rank::criterion::*;
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
|
/// struct TimeOnly {
|
||||||
|
/// time: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let builder = CriteriaBuilder::with_capacity(8)
|
||||||
|
/// .add(SumOfTypos)
|
||||||
|
/// .add(NumberOfWords)
|
||||||
|
/// .add(WordsProximity)
|
||||||
|
/// .add(SumOfWordsAttribute)
|
||||||
|
/// .add(SumOfWordsPosition)
|
||||||
|
/// .add(Exact)
|
||||||
|
/// .add(SortBy::<TimeOnly>::new())
|
||||||
|
/// .add(DocumentId);
|
||||||
|
///
|
||||||
|
/// let criterion = builder.build();
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SortBy<T> {
|
||||||
|
_phantom: marker::PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SortBy<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
SortBy { _phantom: marker::PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, D> Criterion<D> for SortBy<T>
|
||||||
|
where D: Deref<Target=DB>,
|
||||||
|
T: DeserializeOwned + Ord,
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> Ordering {
|
||||||
|
let lhs = match view.retrieve_document::<T>(lhs.id) {
|
||||||
|
Ok(doc) => Some(doc),
|
||||||
|
Err(e) => { eprintln!("{}", e); None },
|
||||||
|
};
|
||||||
|
|
||||||
|
let rhs = match view.retrieve_document::<T>(rhs.id) {
|
||||||
|
Ok(doc) => Some(doc),
|
||||||
|
Err(e) => { eprintln!("{}", e); None },
|
||||||
|
};
|
||||||
|
|
||||||
|
lhs.cmp(&rhs)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user