Skip to main content

os_query_builder_rs/
lib.rs

1//! OpenSearch Query Builder for Rust
2//!
3//! This library provides a type-safe, builder-pattern API for constructing
4//! OpenSearch queries. It supports various query types including term-level queries,
5//! full-text queries, and compound queries.
6//!
7//! # Features
8//!
9//! - **Type-safe query building**: Compile-time checking of query structure
10//! - **Builder pattern**: Fluent API for constructing complex queries
11//! - **Comprehensive coverage**: Support for most OpenSearch query types
12//! - **Serialization**: Automatic JSON serialization using Serde
13//!
14//! # Quick Start
15//!
16//! ```rust
17//! use os_query_builder_rs::model::Query;
18//! use os_query_builder_rs::term::term::Term;
19//!
20//! // Create a simple term query
21//! let query = Query::new()
22//!     .query(Term::new("field", "value"));
23//!
24//! // Serialize to JSON
25//! let json = serde_json::to_string(&query).unwrap();
26//! ```
27//!
28//! # Query Types
29//!
30//! - **Term-level queries**: `Term`, `Terms`, `Range`, `Exists`, etc.
31//! - **Full-text queries**: `Match`, `MultiMatch`, `QueryString`, etc.
32//! - **Compound queries**: `Bool`, `Boosting`, `ConstantScore`, etc.
33//!
34//! # Examples
35//!
36//! See the individual module documentation and test files for more examples.
37//!
38//! # Crate Organization
39//!
40//! - [`model`] - Core query structure and builder
41//! - [`term`] - Term-level queries
42//! - [`full_text`] - Full-text search queries
43//! - [`compound_query`] - Compound query combinators
44//! - [`misc`] - Supporting types and utilities
45
46pub mod compound_query;
47pub mod full_text;
48pub mod misc;
49pub mod term;
50
51/// Core query model and builder types
52pub mod model {
53    use crate::misc::query_field::QueryField;
54    use serde::Serialize;
55    use serde_json::Value;
56
57    /// Examples
58    /// ```
59    /// use os_query_builder_rs::full_text::multi_match::MultiMatch;
60    /// use os_query_builder_rs::misc::operator::Operator;
61    /// use os_query_builder_rs::misc::query_field::QueryField;
62    /// use os_query_builder_rs::misc::r#type::Type;
63    /// use os_query_builder_rs::model::Query;
64    ///
65    /// let multi_match = MultiMatch::new()
66    ///             .fields(vec!["brands", "articles"])
67    ///             .value("oc47")
68    ///             .operator(Operator::And)
69    ///             .query_type(Type::BestFields)
70    ///             .boost(2)
71    ///             .minimum_should_match("90%");
72    ///
73    /// let query = Query::new()
74    ///             .source(vec!["test"])
75    ///             .query(multi_match);
76    /// ```
77    #[derive(Debug, Default, Clone, Serialize)]
78    pub struct Query {
79        #[serde(skip_serializing_if = "Option::is_none")]
80        from: Option<usize>,
81
82        #[serde(skip_serializing_if = "Option::is_none")]
83        size: Option<usize>,
84
85        #[serde(rename = "_source", skip_serializing_if = "Option::is_none")]
86        source: Option<Vec<String>>,
87
88        #[serde(skip_serializing_if = "Option::is_none")]
89        query: Option<QueryField>,
90
91        #[serde(skip_serializing_if = "Option::is_none")]
92        aggs: Option<Value>,
93    }
94
95    impl Query {
96        pub fn new() -> Self {
97            Self::default()
98        }
99
100        pub fn source<F, T>(self, source: F) -> Self
101        where
102            F: IntoIterator<Item = T>,
103            T: Into<String>,
104        {
105            Self {
106                source: Some(source.into_iter().map(|x| x.into()).collect()),
107                ..self
108            }
109        }
110
111        pub fn query<T: Into<QueryField> + Serialize>(self, query: T) -> Self {
112            Self {
113                query: Some(query.into()),
114                ..self
115            }
116        }
117
118        pub fn from<T: Into<usize> + Serialize>(self, from: T) -> Self {
119            Self {
120                from: Some(from.into()),
121                ..self
122            }
123        }
124
125        pub fn size<T: Into<usize> + Serialize>(self, size: T) -> Self {
126            Self {
127                size: Some(size.into()),
128                ..self
129            }
130        }
131
132        pub fn aggs<T: Into<Value> + Serialize>(self, aggs: T) -> Self {
133            Self {
134                aggs: Some(aggs.into()),
135                ..self
136            }
137        }
138    }
139}