subgraph/data_sources/mongo/services/
mod.rs1use bson::{doc, Document};
2use log::{debug, trace};
3
4use crate::filter_operator::FilterOperator;
5
6mod create_one;
7mod find_many;
8mod find_one;
9mod update_many;
10mod update_one;
11
12#[derive(Debug)]
13pub struct Services;
14
15impl Services {
16 pub fn create_nested_fields(doc: &Document) -> Document {
17 debug!("Creating Nested Filter");
18 let mut set_doc = Document::new();
19 for (key, value) in doc.iter() {
20 if let Some(sub_doc) = value.as_document() {
21 debug!("Found Sub Document: {:?}", sub_doc);
22 let sub_set_doc = Services::create_nested_fields(sub_doc);
23 for (sub_key, sub_value) in sub_set_doc.iter() {
24 let nested_key = format!("{}.{}", key, sub_key);
25 set_doc.insert(nested_key, sub_value.clone());
26 }
27 } else {
28 set_doc.insert(key.clone(), value.clone());
29 }
30 }
31 debug!("Created Nested Filter: {:?}", set_doc);
32 set_doc
33 }
34
35 pub fn create_nested_find_filter(query_doc: &Document) -> Document {
37 debug!("Creating Nested Find Filter");
38 trace!("Query Doc: {:?}", query_doc);
39 let mut find_doc = Document::new();
40 for (key, value) in query_doc.clone().iter_mut() {
41 if let Some(sub_doc) = value.as_document() {
43 trace!("Found Sub Document: {:?}", sub_doc);
44 let sub_set_doc = Services::create_nested_find_filter(sub_doc);
45 for (sub_key, sub_value) in sub_set_doc.iter() {
46 let is_filter_operator =
47 FilterOperator::list_mongo_operators().contains(sub_key);
48 if is_filter_operator {
49 let filter_operator = FilterOperator::from_str(sub_key).unwrap();
50 let filter = FilterOperator::convert_value_to_mongo(
51 &filter_operator,
52 key,
53 sub_value,
54 );
55 trace!("Inserted Filter: {:?}", filter);
56 find_doc.insert(key.clone(), filter);
57 } else {
58 let nested_key = format!("{}.{}", key, sub_key);
59 find_doc.insert(nested_key, sub_value.clone());
60 }
61 }
62 } else {
63 if let Some(array) = value.as_array() {
64 trace!("Found Array: {:?}", array);
65 if key == "$and" || key == "$or" {
67 let mut docs = vec![];
68 for b in array {
69 let find_filter =
70 Services::create_nested_find_filter(b.as_document().unwrap());
71 docs.push(find_filter);
72 }
73 find_doc.insert(key.clone(), docs);
74 continue;
75 }
76
77 trace!("Checking if array is docs");
79 let is_docs = array.iter().all(|bson| bson.as_document().is_some());
80 if is_docs {
81 let mut docs = vec![];
82 for b in array {
83 docs.push(doc! { key.clone(): {"$elemMatch": b}})
84 }
85 if docs.len() > 0 {
86 find_doc.insert("$and", docs);
87 } else {
88 find_doc.insert(key.clone(), doc! { "$in": array });
89 }
90 } else {
91 trace!("Array is not docs");
93 find_doc.insert(key.clone(), doc! { "$in": array });
94 }
95 continue;
96 }
97 trace!("Found Primitive: {:?}", value);
99 find_doc.insert(key.clone(), value.clone());
100 }
101 }
102 debug!("Created Nested Find Filter");
103 trace!("Nested Find Filter: {:?}", find_doc);
104 find_doc
105 }
106}