From 187e6740bd1325ba2d4686ed25749d0feb9205a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Thu, 18 Apr 2019 14:11:00 +0200 Subject: [PATCH] feat: Allow users to construct query builders from database indexes --- meilidb-core/src/query_builder.rs | 44 ++++++++++++++++++------------- meilidb-data/src/database.rs | 16 +++++++++++ 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/meilidb-core/src/query_builder.rs b/meilidb-core/src/query_builder.rs index d5ec79a50..4d2327871 100644 --- a/meilidb-core/src/query_builder.rs +++ b/meilidb-core/src/query_builder.rs @@ -1,8 +1,8 @@ -use std::{cmp, mem}; -use std::ops::Range; -use std::time::Instant; use std::hash::Hash; +use std::ops::{Range, Deref}; use std::rc::Rc; +use std::time::Instant; +use std::{cmp, mem}; use rayon::slice::ParallelSliceMut; use slice_group_by::GroupByMut; @@ -35,26 +35,26 @@ fn generate_automatons(query: &str) -> Vec { automatons } -pub struct QueryBuilder<'i, 'c, FI = fn(DocumentId) -> bool> { - index: &'i Index, +pub struct QueryBuilder<'c, I, FI = fn(DocumentId) -> bool> { + index: I, criteria: Criteria<'c>, searchable_attrs: Option>, filter: Option, } -impl<'i, 'c> QueryBuilder<'i, 'c, fn(DocumentId) -> bool> { - pub fn new(index: &'i Index) -> Self { +impl<'c, I> QueryBuilder<'c, I, fn(DocumentId) -> bool> { + pub fn new(index: I) -> Self { QueryBuilder::with_criteria(index, Criteria::default()) } - pub fn with_criteria(index: &'i Index, criteria: Criteria<'c>) -> Self { + pub fn with_criteria(index: I, criteria: Criteria<'c>) -> Self { QueryBuilder { index, criteria, searchable_attrs: None, filter: None } } } -impl<'i, 'c, FI> QueryBuilder<'i, 'c, FI> +impl<'c, I, FI> QueryBuilder<'c, I, FI> { - pub fn with_filter(self, function: F) -> QueryBuilder<'i, 'c, F> + pub fn with_filter(self, function: F) -> QueryBuilder<'c, I, F> where F: Fn(DocumentId) -> bool, { QueryBuilder { @@ -65,7 +65,7 @@ impl<'i, 'c, FI> QueryBuilder<'i, 'c, FI> } } - pub fn with_distinct(self, function: F, size: usize) -> DistinctQueryBuilder<'i, 'c, FI, F> + pub fn with_distinct(self, function: F, size: usize) -> DistinctQueryBuilder<'c, I, FI, F> where F: Fn(DocumentId) -> Option, K: Hash + Eq, { @@ -80,7 +80,11 @@ impl<'i, 'c, FI> QueryBuilder<'i, 'c, FI> let attributes = self.searchable_attrs.get_or_insert_with(HashSet::new); attributes.insert(attribute); } +} +impl<'c, I, FI> QueryBuilder<'c, I, FI> +where I: Deref, +{ fn query_all(&self, query: &str) -> Vec { let automatons = generate_automatons(query); @@ -131,8 +135,9 @@ impl<'i, 'c, FI> QueryBuilder<'i, 'c, FI> } } -impl<'i, 'c, FI> QueryBuilder<'i, 'c, FI> -where FI: Fn(DocumentId) -> bool, +impl<'c, I, FI> QueryBuilder<'c, I, FI> +where I: Deref, + FI: Fn(DocumentId) -> bool, { pub fn query(self, query: &str, range: Range) -> Vec { // We delegate the filter work to the distinct query builder, @@ -184,15 +189,15 @@ where FI: Fn(DocumentId) -> bool, } } -pub struct DistinctQueryBuilder<'i, 'c, FI, FD> { - inner: QueryBuilder<'i, 'c, FI>, +pub struct DistinctQueryBuilder<'c, I, FI, FD> { + inner: QueryBuilder<'c, I, FI>, function: FD, size: usize, } -impl<'i, 'c, FI, FD> DistinctQueryBuilder<'i, 'c, FI, FD> +impl<'c, I, FI, FD> DistinctQueryBuilder<'c, I, FI, FD> { - pub fn with_filter(self, function: F) -> DistinctQueryBuilder<'i, 'c, F, FD> + pub fn with_filter(self, function: F) -> DistinctQueryBuilder<'c, I, F, FD> where F: Fn(DocumentId) -> bool, { DistinctQueryBuilder { @@ -207,8 +212,9 @@ impl<'i, 'c, FI, FD> DistinctQueryBuilder<'i, 'c, FI, FD> } } -impl<'i, 'c, FI, FD, K> DistinctQueryBuilder<'i, 'c, FI, FD> -where FI: Fn(DocumentId) -> bool, +impl<'c, I, FI, FD, K> DistinctQueryBuilder<'c, I, FI, FD> +where I: Deref, + FI: Fn(DocumentId) -> bool, FD: Fn(DocumentId) -> Option, K: Hash + Eq, { diff --git a/meilidb-data/src/database.rs b/meilidb-data/src/database.rs index 6aac48b48..44babb55d 100644 --- a/meilidb-data/src/database.rs +++ b/meilidb-data/src/database.rs @@ -6,6 +6,8 @@ use std::sync::Arc; use arc_swap::{ArcSwap, Lease}; use hashbrown::HashMap; +use meilidb_core::criterion::Criteria; +use meilidb_core::QueryBuilder; use meilidb_core::shared_data_cursor::{FromSharedDataCursor, SharedDataCursor}; use meilidb_core::write_to_bytes::WriteToBytes; use meilidb_core::{DocumentId, Index as WordIndex}; @@ -288,6 +290,20 @@ impl<'a> Iterator for DocumentFieldsIter<'a> { pub struct Index(RawIndex); impl Index { + pub fn query_builder(&self) -> QueryBuilder>> { + let word_index = self.word_index(); + QueryBuilder::new(word_index) + } + + pub fn query_builder_with_criteria<'c>( + &self, + criteria: Criteria<'c>, + ) -> QueryBuilder<'c, Lease>> + { + let word_index = self.word_index(); + QueryBuilder::with_criteria(word_index, criteria) + } + pub fn schema(&self) -> &Schema { self.0.schema() }