mongo-aggro 0.1.0__py3-none-any.whl → 0.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. mongo_aggro/__init__.py +400 -0
  2. mongo_aggro/accumulators.py +30 -12
  3. mongo_aggro/base.py +49 -9
  4. mongo_aggro/expressions/__init__.py +396 -0
  5. mongo_aggro/expressions/arithmetic.py +329 -0
  6. mongo_aggro/expressions/array.py +425 -0
  7. mongo_aggro/expressions/base.py +180 -0
  8. mongo_aggro/expressions/bitwise.py +84 -0
  9. mongo_aggro/expressions/comparison.py +161 -0
  10. mongo_aggro/expressions/conditional.py +117 -0
  11. mongo_aggro/expressions/date.py +665 -0
  12. mongo_aggro/expressions/encrypted.py +116 -0
  13. mongo_aggro/expressions/logical.py +72 -0
  14. mongo_aggro/expressions/object.py +122 -0
  15. mongo_aggro/expressions/set.py +150 -0
  16. mongo_aggro/expressions/size.py +48 -0
  17. mongo_aggro/expressions/string.py +365 -0
  18. mongo_aggro/expressions/trigonometry.py +283 -0
  19. mongo_aggro/expressions/type.py +205 -0
  20. mongo_aggro/expressions/variable.py +73 -0
  21. mongo_aggro/expressions/window.py +327 -0
  22. mongo_aggro/operators/__init__.py +65 -0
  23. mongo_aggro/operators/array.py +41 -0
  24. mongo_aggro/operators/base.py +15 -0
  25. mongo_aggro/operators/bitwise.py +81 -0
  26. mongo_aggro/operators/comparison.py +82 -0
  27. mongo_aggro/operators/element.py +32 -0
  28. mongo_aggro/operators/geo.py +171 -0
  29. mongo_aggro/operators/logical.py +111 -0
  30. mongo_aggro/operators/misc.py +102 -0
  31. mongo_aggro/operators/regex.py +25 -0
  32. mongo_aggro/stages/__init__.py +110 -0
  33. mongo_aggro/stages/array.py +69 -0
  34. mongo_aggro/stages/change.py +109 -0
  35. mongo_aggro/stages/core.py +170 -0
  36. mongo_aggro/stages/geo.py +93 -0
  37. mongo_aggro/stages/group.py +154 -0
  38. mongo_aggro/stages/join.py +221 -0
  39. mongo_aggro/stages/misc.py +45 -0
  40. mongo_aggro/stages/output.py +136 -0
  41. mongo_aggro/stages/search.py +315 -0
  42. mongo_aggro/stages/session.py +111 -0
  43. mongo_aggro/stages/stats.py +152 -0
  44. mongo_aggro/stages/transform.py +136 -0
  45. mongo_aggro/stages/window.py +139 -0
  46. mongo_aggro-0.2.2.dist-info/METADATA +193 -0
  47. mongo_aggro-0.2.2.dist-info/RECORD +49 -0
  48. {mongo_aggro-0.1.0.dist-info → mongo_aggro-0.2.2.dist-info}/WHEEL +1 -1
  49. mongo_aggro/operators.py +0 -247
  50. mongo_aggro/stages.py +0 -990
  51. mongo_aggro-0.1.0.dist-info/METADATA +0 -537
  52. mongo_aggro-0.1.0.dist-info/RECORD +0 -9
  53. {mongo_aggro-0.1.0.dist-info → mongo_aggro-0.2.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,161 @@
1
+ """Comparison expression operators for MongoDB aggregation."""
2
+
3
+ from typing import Any
4
+
5
+ from pydantic import model_serializer
6
+
7
+ from mongo_aggro.base import serialize_value
8
+ from mongo_aggro.expressions.base import ExpressionBase
9
+
10
+
11
+ class EqExpr(ExpressionBase):
12
+ """
13
+ $eq expression operator - tests equality.
14
+
15
+ Example:
16
+ >>> EqExpr(left=F("status"), right="active").model_dump()
17
+ {"$eq": ["$status", "active"]}
18
+ """
19
+
20
+ left: Any
21
+ right: Any
22
+
23
+ @model_serializer
24
+ def serialize(self) -> dict[str, Any]:
25
+ """Serialize to MongoDB $eq expression."""
26
+ return {
27
+ "$eq": [serialize_value(self.left), serialize_value(self.right)]
28
+ }
29
+
30
+
31
+ class NeExpr(ExpressionBase):
32
+ """
33
+ $ne expression operator - tests inequality.
34
+
35
+ Example:
36
+ >>> NeExpr(left=F("status"), right="deleted").model_dump()
37
+ {"$ne": ["$status", "deleted"]}
38
+ """
39
+
40
+ left: Any
41
+ right: Any
42
+
43
+ @model_serializer
44
+ def serialize(self) -> dict[str, Any]:
45
+ """Serialize to MongoDB $ne expression."""
46
+ return {
47
+ "$ne": [serialize_value(self.left), serialize_value(self.right)]
48
+ }
49
+
50
+
51
+ class GtExpr(ExpressionBase):
52
+ """
53
+ $gt expression operator - tests greater than.
54
+
55
+ Example:
56
+ >>> GtExpr(left=F("age"), right=18).model_dump()
57
+ {"$gt": ["$age", 18]}
58
+ """
59
+
60
+ left: Any
61
+ right: Any
62
+
63
+ @model_serializer
64
+ def serialize(self) -> dict[str, Any]:
65
+ """Serialize to MongoDB $gt expression."""
66
+ return {
67
+ "$gt": [serialize_value(self.left), serialize_value(self.right)]
68
+ }
69
+
70
+
71
+ class GteExpr(ExpressionBase):
72
+ """
73
+ $gte expression operator - tests greater than or equal.
74
+
75
+ Example:
76
+ >>> GteExpr(left=F("age"), right=18).model_dump()
77
+ {"$gte": ["$age", 18]}
78
+ """
79
+
80
+ left: Any
81
+ right: Any
82
+
83
+ @model_serializer
84
+ def serialize(self) -> dict[str, Any]:
85
+ """Serialize to MongoDB $gte expression."""
86
+ return {
87
+ "$gte": [serialize_value(self.left), serialize_value(self.right)]
88
+ }
89
+
90
+
91
+ class LtExpr(ExpressionBase):
92
+ """
93
+ $lt expression operator - tests less than.
94
+
95
+ Example:
96
+ >>> LtExpr(left=F("age"), right=65).model_dump()
97
+ {"$lt": ["$age", 65]}
98
+ """
99
+
100
+ left: Any
101
+ right: Any
102
+
103
+ @model_serializer
104
+ def serialize(self) -> dict[str, Any]:
105
+ """Serialize to MongoDB $lt expression."""
106
+ return {
107
+ "$lt": [serialize_value(self.left), serialize_value(self.right)]
108
+ }
109
+
110
+
111
+ class LteExpr(ExpressionBase):
112
+ """
113
+ $lte expression operator - tests less than or equal.
114
+
115
+ Example:
116
+ >>> LteExpr(left=F("age"), right=65).model_dump()
117
+ {"$lte": ["$age", 65]}
118
+ """
119
+
120
+ left: Any
121
+ right: Any
122
+
123
+ @model_serializer
124
+ def serialize(self) -> dict[str, Any]:
125
+ """Serialize to MongoDB $lte expression."""
126
+ return {
127
+ "$lte": [serialize_value(self.left), serialize_value(self.right)]
128
+ }
129
+
130
+
131
+ class CmpExpr(ExpressionBase):
132
+ """
133
+ $cmp expression operator - compares two values.
134
+
135
+ Returns -1 if first < second, 0 if equal, 1 if first > second.
136
+
137
+ Example:
138
+ >>> CmpExpr(left=F("a"), right=F("b")).model_dump()
139
+ {"$cmp": ["$a", "$b"]}
140
+ """
141
+
142
+ left: Any
143
+ right: Any
144
+
145
+ @model_serializer
146
+ def serialize(self) -> dict[str, Any]:
147
+ """Serialize to MongoDB $cmp expression."""
148
+ return {
149
+ "$cmp": [serialize_value(self.left), serialize_value(self.right)]
150
+ }
151
+
152
+
153
+ __all__ = [
154
+ "EqExpr",
155
+ "NeExpr",
156
+ "GtExpr",
157
+ "GteExpr",
158
+ "LtExpr",
159
+ "LteExpr",
160
+ "CmpExpr",
161
+ ]
@@ -0,0 +1,117 @@
1
+ """Conditional expression operators for MongoDB aggregation."""
2
+
3
+ from typing import Any
4
+
5
+ from pydantic import BaseModel, ConfigDict, model_serializer
6
+
7
+ from mongo_aggro.base import serialize_value
8
+ from mongo_aggro.expressions.base import ExpressionBase
9
+
10
+
11
+ class CondExpr(ExpressionBase):
12
+ """
13
+ $cond expression operator - ternary conditional.
14
+
15
+ Example:
16
+ >>> CondExpr(
17
+ ... if_=GtExpr(left=F("qty"), right=100),
18
+ ... then="bulk",
19
+ ... else_="retail"
20
+ ... ).model_dump()
21
+ {"$cond": {"if": {"$gt": ["$qty", 100]}, "then": "bulk", "else": "retail"}}
22
+ """
23
+
24
+ if_: Any
25
+ then: Any
26
+ else_: Any
27
+
28
+ @model_serializer
29
+ def serialize(self) -> dict[str, Any]:
30
+ """Serialize to MongoDB $cond expression."""
31
+ return {
32
+ "$cond": {
33
+ "if": serialize_value(self.if_),
34
+ "then": serialize_value(self.then),
35
+ "else": serialize_value(self.else_),
36
+ }
37
+ }
38
+
39
+
40
+ class IfNullExpr(ExpressionBase):
41
+ """
42
+ $ifNull expression operator - null coalescing.
43
+
44
+ Example:
45
+ >>> IfNullExpr(input=F("name"), replacement="Unknown").model_dump()
46
+ {"$ifNull": ["$name", "Unknown"]}
47
+ """
48
+
49
+ input: Any
50
+ replacement: Any
51
+
52
+ @model_serializer
53
+ def serialize(self) -> dict[str, Any]:
54
+ """Serialize to MongoDB $ifNull expression."""
55
+ return {
56
+ "$ifNull": [
57
+ serialize_value(self.input),
58
+ serialize_value(self.replacement),
59
+ ]
60
+ }
61
+
62
+
63
+ class SwitchBranch(BaseModel):
64
+ """A single branch in a $switch expression."""
65
+
66
+ model_config = ConfigDict(
67
+ populate_by_name=True,
68
+ extra="forbid",
69
+ )
70
+
71
+ case: Any
72
+ then: Any
73
+
74
+
75
+ class SwitchExpr(ExpressionBase):
76
+ """
77
+ $switch expression operator - multi-branch conditional.
78
+
79
+ Example:
80
+ >>> SwitchExpr(
81
+ ... branches=[
82
+ ... SwitchBranch(case=EqExpr(left=F("status"), right="A"), then=1),
83
+ ... SwitchBranch(case=EqExpr(left=F("status"), right="B"), then=2),
84
+ ... ],
85
+ ... default=0
86
+ ... ).model_dump()
87
+ {"$switch": {"branches": [...], "default": 0}}
88
+ """
89
+
90
+ branches: list[SwitchBranch]
91
+ default: Any = None
92
+
93
+ @model_serializer
94
+ def serialize(self) -> dict[str, Any]:
95
+ """Serialize to MongoDB $switch expression."""
96
+ result: dict[str, Any] = {
97
+ "$switch": {
98
+ "branches": [
99
+ {
100
+ "case": serialize_value(b.case),
101
+ "then": serialize_value(b.then),
102
+ }
103
+ for b in self.branches
104
+ ]
105
+ }
106
+ }
107
+ if self.default is not None:
108
+ result["$switch"]["default"] = serialize_value(self.default)
109
+ return result
110
+
111
+
112
+ __all__ = [
113
+ "CondExpr",
114
+ "IfNullExpr",
115
+ "SwitchBranch",
116
+ "SwitchExpr",
117
+ ]