2021-10-27 18:16:13 +02:00
|
|
|
mod mock_analytics;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(feature = "analytics")]
|
2021-10-27 18:16:13 +02:00
|
|
|
mod segment_analytics;
|
|
|
|
|
|
|
|
use std::fs;
|
|
|
|
use std::path::{Path, PathBuf};
|
2022-10-13 15:02:59 +02:00
|
|
|
use std::str::FromStr;
|
2021-10-27 18:16:13 +02:00
|
|
|
|
|
|
|
use actix_web::HttpRequest;
|
2022-10-13 15:02:59 +02:00
|
|
|
use meilisearch_types::InstanceUid;
|
2022-10-20 18:00:07 +02:00
|
|
|
pub use mock_analytics::MockAnalytics;
|
2021-10-27 18:16:13 +02:00
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
use platform_dirs::AppDirs;
|
|
|
|
use serde_json::Value;
|
|
|
|
|
2024-07-08 16:30:50 +02:00
|
|
|
use crate::routes::indexes::documents::{DocumentEditionByFunction, UpdateDocumentsQuery};
|
2021-10-27 18:16:13 +02:00
|
|
|
|
2023-09-21 17:01:05 +02:00
|
|
|
// if the analytics feature is disabled
|
2021-10-27 18:16:13 +02:00
|
|
|
// the `SegmentAnalytics` point to the mock instead of the real analytics
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(not(feature = "analytics"))]
|
2021-10-28 16:28:41 +02:00
|
|
|
pub type SegmentAnalytics = mock_analytics::MockAnalytics;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(not(feature = "analytics"))]
|
2021-10-28 16:28:41 +02:00
|
|
|
pub type SearchAggregator = mock_analytics::SearchAggregator;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(not(feature = "analytics"))]
|
2024-05-27 10:54:12 +02:00
|
|
|
pub type SimilarAggregator = mock_analytics::SimilarAggregator;
|
|
|
|
#[cfg(not(feature = "analytics"))]
|
2023-02-20 09:21:52 +01:00
|
|
|
pub type MultiSearchAggregator = mock_analytics::MultiSearchAggregator;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(not(feature = "analytics"))]
|
2023-04-26 17:08:55 +02:00
|
|
|
pub type FacetSearchAggregator = mock_analytics::FacetSearchAggregator;
|
2021-10-27 18:16:13 +02:00
|
|
|
|
2023-09-21 17:01:05 +02:00
|
|
|
// if the feature analytics is enabled we use the real analytics
|
|
|
|
#[cfg(feature = "analytics")]
|
2021-10-27 18:16:13 +02:00
|
|
|
pub type SegmentAnalytics = segment_analytics::SegmentAnalytics;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(feature = "analytics")]
|
2021-10-28 16:28:41 +02:00
|
|
|
pub type SearchAggregator = segment_analytics::SearchAggregator;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(feature = "analytics")]
|
2024-05-27 10:54:12 +02:00
|
|
|
pub type SimilarAggregator = segment_analytics::SimilarAggregator;
|
|
|
|
#[cfg(feature = "analytics")]
|
2023-02-20 09:21:52 +01:00
|
|
|
pub type MultiSearchAggregator = segment_analytics::MultiSearchAggregator;
|
2023-09-21 17:01:05 +02:00
|
|
|
#[cfg(feature = "analytics")]
|
2023-04-26 17:08:55 +02:00
|
|
|
pub type FacetSearchAggregator = segment_analytics::FacetSearchAggregator;
|
2021-10-27 18:16:13 +02:00
|
|
|
|
2022-01-26 17:43:16 +01:00
|
|
|
/// The Meilisearch config dir:
|
|
|
|
/// `~/.config/Meilisearch` on *NIX or *BSD.
|
2021-10-27 18:16:13 +02:00
|
|
|
/// `~/Library/ApplicationSupport` on macOS.
|
|
|
|
/// `%APPDATA` (= `C:\Users%USERNAME%\AppData\Roaming`) on windows.
|
|
|
|
static MEILISEARCH_CONFIG_PATH: Lazy<Option<PathBuf>> =
|
2022-01-26 17:43:16 +01:00
|
|
|
Lazy::new(|| AppDirs::new(Some("Meilisearch"), false).map(|appdir| appdir.config_dir));
|
2021-10-27 18:16:13 +02:00
|
|
|
|
|
|
|
fn config_user_id_path(db_path: &Path) -> Option<PathBuf> {
|
|
|
|
db_path
|
|
|
|
.canonicalize()
|
|
|
|
.ok()
|
2022-10-20 18:00:07 +02:00
|
|
|
.map(|path| path.join("instance-uid").display().to_string().replace('/', "-"))
|
2021-10-27 18:16:13 +02:00
|
|
|
.zip(MEILISEARCH_CONFIG_PATH.as_ref())
|
|
|
|
.map(|(filename, config_path)| config_path.join(filename.trim_start_matches('-')))
|
|
|
|
}
|
|
|
|
|
2022-01-26 17:43:16 +01:00
|
|
|
/// Look for the instance-uid in the `data.ms` or in `~/.config/Meilisearch/path-to-db-instance-uid`
|
2022-10-13 15:02:59 +02:00
|
|
|
fn find_user_id(db_path: &Path) -> Option<InstanceUid> {
|
2021-10-27 18:16:13 +02:00
|
|
|
fs::read_to_string(db_path.join("instance-uid"))
|
|
|
|
.ok()
|
2022-12-19 14:12:26 +01:00
|
|
|
.or_else(|| fs::read_to_string(config_user_id_path(db_path)?).ok())
|
2022-10-13 15:02:59 +02:00
|
|
|
.and_then(|uid| InstanceUid::from_str(&uid).ok())
|
2021-10-27 18:16:13 +02:00
|
|
|
}
|
|
|
|
|
2022-11-28 16:27:41 +01:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum DocumentDeletionKind {
|
|
|
|
PerDocumentId,
|
|
|
|
ClearAll,
|
|
|
|
PerBatch,
|
2023-05-02 17:46:04 +02:00
|
|
|
PerFilter,
|
2022-11-28 16:27:41 +01:00
|
|
|
}
|
|
|
|
|
2023-05-09 19:52:11 +02:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum DocumentFetchKind {
|
2024-06-06 11:29:16 +02:00
|
|
|
PerDocumentId { retrieve_vectors: bool },
|
|
|
|
Normal { with_filter: bool, limit: usize, offset: usize, retrieve_vectors: bool },
|
2023-05-09 19:52:11 +02:00
|
|
|
}
|
|
|
|
|
2021-10-29 15:58:06 +02:00
|
|
|
pub trait Analytics: Sync + Send {
|
2022-10-13 15:02:59 +02:00
|
|
|
fn instance_uid(&self) -> Option<&InstanceUid>;
|
|
|
|
|
2021-10-27 18:16:13 +02:00
|
|
|
/// The method used to publish most analytics that do not need to be batched every hours
|
2021-10-29 15:58:06 +02:00
|
|
|
fn publish(&self, event_name: String, send: Value, request: Option<&HttpRequest>);
|
2021-10-27 18:16:13 +02:00
|
|
|
|
2022-06-11 17:21:05 +02:00
|
|
|
/// This method should be called to aggregate a get search
|
2021-10-29 15:58:06 +02:00
|
|
|
fn get_search(&self, aggregate: SearchAggregator);
|
2021-10-27 18:16:13 +02:00
|
|
|
|
2021-10-28 16:28:41 +02:00
|
|
|
/// This method should be called to aggregate a post search
|
2021-10-29 15:58:06 +02:00
|
|
|
fn post_search(&self, aggregate: SearchAggregator);
|
2021-10-27 18:16:13 +02:00
|
|
|
|
2024-05-27 10:54:12 +02:00
|
|
|
/// This method should be called to aggregate a get similar request
|
|
|
|
fn get_similar(&self, aggregate: SimilarAggregator);
|
|
|
|
|
|
|
|
/// This method should be called to aggregate a post similar request
|
|
|
|
fn post_similar(&self, aggregate: SimilarAggregator);
|
|
|
|
|
2023-02-20 09:21:52 +01:00
|
|
|
/// This method should be called to aggregate a post array of searches
|
|
|
|
fn post_multi_search(&self, aggregate: MultiSearchAggregator);
|
|
|
|
|
2023-04-26 17:08:55 +02:00
|
|
|
/// This method should be called to aggregate post facet values searches
|
|
|
|
fn post_facet_search(&self, aggregate: FacetSearchAggregator);
|
|
|
|
|
2024-07-08 23:27:10 +02:00
|
|
|
// this method should be called to aggregate an add documents request
|
2021-10-27 18:16:13 +02:00
|
|
|
fn add_documents(
|
2021-10-29 15:58:06 +02:00
|
|
|
&self,
|
2021-10-27 18:16:13 +02:00
|
|
|
documents_query: &UpdateDocumentsQuery,
|
|
|
|
index_creation: bool,
|
|
|
|
request: &HttpRequest,
|
|
|
|
);
|
2022-11-28 16:27:41 +01:00
|
|
|
|
2023-05-09 19:52:11 +02:00
|
|
|
// this method should be called to aggregate a fetch documents request
|
|
|
|
fn get_fetch_documents(&self, documents_query: &DocumentFetchKind, request: &HttpRequest);
|
|
|
|
|
|
|
|
// this method should be called to aggregate a fetch documents request
|
|
|
|
fn post_fetch_documents(&self, documents_query: &DocumentFetchKind, request: &HttpRequest);
|
|
|
|
|
2022-11-28 16:27:41 +01:00
|
|
|
// this method should be called to aggregate a add documents request
|
|
|
|
fn delete_documents(&self, kind: DocumentDeletionKind, request: &HttpRequest);
|
|
|
|
|
2024-07-08 16:30:50 +02:00
|
|
|
// this method should be called to batch an update documents request
|
2021-10-27 18:16:13 +02:00
|
|
|
fn update_documents(
|
2021-10-29 15:58:06 +02:00
|
|
|
&self,
|
2021-10-27 18:16:13 +02:00
|
|
|
documents_query: &UpdateDocumentsQuery,
|
|
|
|
index_creation: bool,
|
|
|
|
request: &HttpRequest,
|
|
|
|
);
|
2024-07-08 16:30:50 +02:00
|
|
|
|
|
|
|
// this method should be called to batch an update documents by function request
|
|
|
|
fn update_documents_by_function(
|
|
|
|
&self,
|
|
|
|
documents_query: &DocumentEditionByFunction,
|
|
|
|
index_creation: bool,
|
|
|
|
request: &HttpRequest,
|
|
|
|
);
|
2021-10-27 18:16:13 +02:00
|
|
|
}
|