-
-
Notifications
You must be signed in to change notification settings - Fork 570
/
filter.h
122 lines (98 loc) · 3.87 KB
/
filter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#pragma once
#include <string>
#include <map>
#include "tsl/htrie_map.h"
#include "json.hpp"
#include "store.h"
enum NUM_COMPARATOR {
LESS_THAN,
LESS_THAN_EQUALS,
EQUALS,
NOT_EQUALS,
CONTAINS,
GREATER_THAN,
GREATER_THAN_EQUALS,
RANGE_INCLUSIVE
};
enum FILTER_OPERATOR {
AND,
OR
};
struct filter_node_t;
struct field;
struct filter {
std::string field_name;
std::vector<std::string> values;
std::vector<NUM_COMPARATOR> comparators;
// Would be set when `field: != ...` is encountered with id/string field or `field: != [ ... ]` is encountered in the
// case of int and float fields. During filtering, all the results of matching the field against the values are
// aggregated and then this flag is checked if negation on the aggregated result is required.
bool apply_not_equals = false;
// Would store `Foo` in case of a filter expression like `$Foo(bar := baz)`
std::string referenced_collection_name;
std::vector<nlohmann::json> params;
/// For searching places within a given radius of a given latlong (mi for miles and km for kilometers)
static constexpr const char* GEO_FILTER_RADIUS_KEY = "radius";
/// Radius threshold beyond which exact filtering on geo_result_ids will not be done.
static constexpr const char* EXACT_GEO_FILTER_RADIUS_KEY = "exact_filter_radius";
static constexpr double DEFAULT_EXACT_GEO_FILTER_RADIUS_VALUE = 10000; // meters
static const std::string RANGE_OPERATOR() {
return "..";
}
static Option<bool> validate_numerical_filter_value(field _field, const std::string& raw_value);
static Option<NUM_COMPARATOR> extract_num_comparator(std::string & comp_and_value);
static Option<bool> parse_geopoint_filter_value(std::string& raw_value,
const std::string& format_err_msg,
std::string& processed_filter_val,
NUM_COMPARATOR& num_comparator);
static Option<bool> parse_geopoint_filter_value(std::string& raw_value,
const std::string& format_err_msg,
filter& filter_exp);
static Option<bool> parse_filter_query(const std::string& filter_query,
const tsl::htrie_map<char, field>& search_schema,
const Store* store,
const std::string& doc_id_prefix,
filter_node_t*& root);
};
struct filter_node_t {
filter filter_exp;
FILTER_OPERATOR filter_operator = AND;
bool isOperator = false;
filter_node_t* left = nullptr;
filter_node_t* right = nullptr;
std::string filter_query;
filter_node_t() = default;
explicit filter_node_t(filter filter_exp)
: filter_exp(std::move(filter_exp)),
isOperator(false),
left(nullptr),
right(nullptr) {}
filter_node_t(FILTER_OPERATOR filter_operator,
filter_node_t* left,
filter_node_t* right)
: filter_operator(filter_operator),
isOperator(true),
left(left),
right(right) {}
~filter_node_t() {
delete left;
delete right;
}
filter_node_t& operator=(filter_node_t&& obj) noexcept {
if (&obj == this) {
return *this;
}
if (obj.isOperator) {
isOperator = true;
filter_operator = obj.filter_operator;
left = obj.left;
right = obj.right;
obj.left = nullptr;
obj.right = nullptr;
} else {
isOperator = false;
filter_exp = obj.filter_exp;
}
return *this;
}
};