MeiliSearch/meilisearch-http/src/index/mod.rs

139 lines
4.0 KiB
Rust
Raw Normal View History

2021-03-04 11:56:32 +01:00
mod search;
mod updates;
use std::ops::Deref;
use std::sync::Arc;
2021-03-04 11:56:32 +01:00
2021-03-04 15:09:00 +01:00
use anyhow::{bail, Context};
2021-03-04 14:20:19 +01:00
use milli::obkv_to_json;
use serde_json::{Map, Value};
2021-03-04 14:20:19 +01:00
2021-03-04 11:56:32 +01:00
pub use search::{SearchQuery, SearchResult, DEFAULT_SEARCH_LIMIT};
pub use updates::{Facets, Settings, UpdateResult};
2021-03-04 11:56:32 +01:00
2021-03-04 14:20:19 +01:00
pub type Document = Map<String, Value>;
2021-03-04 11:56:32 +01:00
#[derive(Clone)]
pub struct Index(pub Arc<milli::Index>);
impl Deref for Index {
type Target = milli::Index;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
2021-03-04 12:38:55 +01:00
impl Index {
pub fn settings(&self) -> anyhow::Result<Settings> {
let txn = self.read_txn()?;
let displayed_attributes = self
.displayed_fields(&txn)?
.map(|fields| fields.into_iter().map(String::from).collect())
.unwrap_or_else(|| vec!["*".to_string()]);
let searchable_attributes = self
.searchable_fields(&txn)?
.map(|fields| fields.into_iter().map(String::from).collect())
.unwrap_or_else(|| vec!["*".to_string()]);
let faceted_attributes = self
.faceted_fields(&txn)?
.into_iter()
.map(|(k, v)| (k, v.to_string()))
.collect();
2021-03-11 22:39:16 +01:00
let criteria = self
.criteria(&txn)?
.into_iter()
.map(|c| c.to_string())
.collect();
2021-03-04 12:38:55 +01:00
Ok(Settings {
displayed_attributes: Some(Some(displayed_attributes)),
searchable_attributes: Some(Some(searchable_attributes)),
faceted_attributes: Some(Some(faceted_attributes)),
2021-03-11 22:39:16 +01:00
ranking_rules: Some(Some(criteria)),
2021-03-04 12:38:55 +01:00
})
}
2021-03-04 14:20:19 +01:00
pub fn retrieve_documents<S>(
&self,
offset: usize,
limit: usize,
attributes_to_retrieve: Option<Vec<S>>,
) -> anyhow::Result<Vec<Map<String, Value>>>
where
S: AsRef<str> + Send + Sync + 'static,
{
let txn = self.read_txn()?;
let fields_ids_map = self.fields_ids_map(&txn)?;
let attributes_to_retrieve_ids = match attributes_to_retrieve {
Some(attrs) => attrs
.iter()
.filter_map(|f| fields_ids_map.id(f.as_ref()))
.collect::<Vec<_>>(),
None => match self.displayed_fields_ids(&txn)? {
Some(fields) => fields,
None => fields_ids_map.iter().map(|(id, _)| id).collect(),
},
2021-03-04 14:20:19 +01:00
};
let iter = self.documents.range(&txn, &(..))?.skip(offset).take(limit);
let mut documents = Vec::new();
for entry in iter {
let (_id, obkv) = entry?;
let object = obkv_to_json(&attributes_to_retrieve_ids, &fields_ids_map, obkv)?;
documents.push(object);
}
Ok(documents)
}
2021-03-04 15:09:00 +01:00
pub fn retrieve_document<S: AsRef<str>>(
&self,
doc_id: String,
attributes_to_retrieve: Option<Vec<S>>,
) -> anyhow::Result<Map<String, Value>> {
let txn = self.read_txn()?;
2021-03-04 15:09:00 +01:00
let fields_ids_map = self.fields_ids_map(&txn)?;
2021-03-04 15:09:00 +01:00
let attributes_to_retrieve_ids = match attributes_to_retrieve {
Some(attrs) => attrs
.iter()
.filter_map(|f| fields_ids_map.id(f.as_ref()))
.collect::<Vec<_>>(),
None => match self.displayed_fields_ids(&txn)? {
Some(fields) => fields,
2021-03-04 15:09:00 +01:00
None => fields_ids_map.iter().map(|(id, _)| id).collect(),
},
};
let internal_id = self
.external_documents_ids(&txn)?
.get(doc_id.as_bytes())
.with_context(|| format!("Document with id {} not found", doc_id))?;
let document = self
.documents(&txn, std::iter::once(internal_id))?
.into_iter()
.next()
.map(|(_, d)| d);
match document {
Some(document) => Ok(obkv_to_json(
&attributes_to_retrieve_ids,
&fields_ids_map,
document,
)?),
None => bail!("Document with id {} not found", doc_id),
}
2021-03-04 15:09:00 +01:00
}
2021-03-04 12:38:55 +01:00
}