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,136 @@
1
+ """Document transformation MongoDB aggregation pipeline stages.
2
+
3
+ This module contains stages for transforming document structure:
4
+ AddFields, Set, Unset, ReplaceRoot, ReplaceWith, and Redact.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from pydantic import BaseModel, ConfigDict, Field
10
+
11
+
12
+ class AddFields(BaseModel):
13
+ """
14
+ $addFields stage - adds new fields to documents.
15
+
16
+ Example:
17
+ >>> AddFields(fields={"isActive": True, "score": {"$sum": "$marks"}})
18
+ {"$addFields": {"isActive": true, "score": {"$sum": "$marks"}}}
19
+ """
20
+
21
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
22
+
23
+ fields: dict[str, Any] = Field(..., description="Fields to add")
24
+
25
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
26
+ return {"$addFields": self.fields}
27
+
28
+
29
+ class Set(BaseModel):
30
+ """
31
+ $set stage - alias for $addFields.
32
+
33
+ Example:
34
+ >>> Set(fields={"status": "processed"}).model_dump()
35
+ {"$set": {"status": "processed"}}
36
+ """
37
+
38
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
39
+
40
+ fields: dict[str, Any] = Field(..., description="Fields to set")
41
+
42
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
43
+ return {"$set": self.fields}
44
+
45
+
46
+ class Unset(BaseModel):
47
+ """
48
+ $unset stage - removes fields from documents.
49
+
50
+ Example:
51
+ >>> Unset(fields=["password", "secret"]).model_dump()
52
+ {"$unset": ["password", "secret"]}
53
+
54
+ >>> Unset(fields="temporaryField").model_dump()
55
+ {"$unset": "temporaryField"}
56
+ """
57
+
58
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
59
+
60
+ fields: str | list[str] = Field(..., description="Field(s) to remove")
61
+
62
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
63
+ return {"$unset": self.fields}
64
+
65
+
66
+ class ReplaceRoot(BaseModel):
67
+ """
68
+ $replaceRoot stage - replaces document with specified embedded document.
69
+
70
+ Example:
71
+ >>> ReplaceRoot(new_root="$nested").model_dump()
72
+ {"$replaceRoot": {"newRoot": "$nested"}}
73
+ """
74
+
75
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
76
+
77
+ new_root: str | dict[str, Any] = Field(
78
+ ...,
79
+ validation_alias="newRoot",
80
+ serialization_alias="newRoot",
81
+ description="Expression for new root",
82
+ )
83
+
84
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
85
+ return {"$replaceRoot": {"newRoot": self.new_root}}
86
+
87
+
88
+ class ReplaceWith(BaseModel):
89
+ """
90
+ $replaceWith stage - replaces document (alias for $replaceRoot).
91
+
92
+ Example:
93
+ >>> ReplaceWith(expression="$embedded").model_dump()
94
+ {"$replaceWith": "$embedded"}
95
+ """
96
+
97
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
98
+
99
+ expression: str | dict[str, Any] = Field(
100
+ ..., description="Expression for new document"
101
+ )
102
+
103
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
104
+ return {"$replaceWith": self.expression}
105
+
106
+
107
+ class Redact(BaseModel):
108
+ """
109
+ $redact stage - restricts document content based on stored info.
110
+
111
+ Example:
112
+ >>> Redact(expression={
113
+ ... "$cond": {
114
+ ... "if": {"$eq": ["$level", 5]},
115
+ ... "then": "$$PRUNE",
116
+ ... "else": "$$DESCEND"
117
+ ... }
118
+ ... }).model_dump()
119
+ """
120
+
121
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
122
+
123
+ expression: dict[str, Any] = Field(..., description="Redaction expression")
124
+
125
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
126
+ return {"$redact": self.expression}
127
+
128
+
129
+ __all__ = [
130
+ "AddFields",
131
+ "Set",
132
+ "Unset",
133
+ "ReplaceRoot",
134
+ "ReplaceWith",
135
+ "Redact",
136
+ ]
@@ -0,0 +1,139 @@
1
+ """Window function MongoDB aggregation pipeline stages.
2
+
3
+ This module contains stages for window operations and data filling:
4
+ SetWindowFields, Densify, and Fill.
5
+ """
6
+
7
+ from typing import Any, Literal
8
+
9
+ from pydantic import BaseModel, ConfigDict, Field
10
+
11
+
12
+ class SetWindowFields(BaseModel):
13
+ """
14
+ $setWindowFields stage - performs window calculations.
15
+
16
+ Example:
17
+ >>> SetWindowFields(
18
+ ... partition_by="$state",
19
+ ... sort_by={"date": 1},
20
+ ... output={
21
+ ... "cumulative": {
22
+ ... "$sum": "$quantity",
23
+ ... "window": {"documents": ["unbounded", "current"]}
24
+ ... }
25
+ ... }
26
+ ... ).model_dump()
27
+ """
28
+
29
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
30
+
31
+ partition_by: str | dict[str, Any] | None = Field(
32
+ default=None,
33
+ validation_alias="partitionBy",
34
+ serialization_alias="partitionBy",
35
+ description="Partitioning expression",
36
+ )
37
+ sort_by: dict[str, Literal[-1, 1]] | None = Field(
38
+ default=None,
39
+ validation_alias="sortBy",
40
+ serialization_alias="sortBy",
41
+ description="Sort specification",
42
+ )
43
+ output: dict[str, Any] = Field(
44
+ ..., description="Output field specifications"
45
+ )
46
+
47
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
48
+ result: dict[str, Any] = {"output": self.output}
49
+ if self.partition_by is not None:
50
+ result["partitionBy"] = self.partition_by
51
+ if self.sort_by is not None:
52
+ result["sortBy"] = self.sort_by
53
+ return {"$setWindowFields": result}
54
+
55
+
56
+ class Densify(BaseModel):
57
+ """
58
+ $densify stage - fills gaps in data.
59
+
60
+ Example:
61
+ >>> Densify(
62
+ ... field="date",
63
+ ... range={"step": 1, "unit": "day", "bounds": "full"},
64
+ ... partition_by_fields=["series"]
65
+ ... ).model_dump()
66
+ """
67
+
68
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
69
+
70
+ field: str = Field(..., description="Field to densify")
71
+ range: dict[str, Any] = Field(..., description="Range specification")
72
+ partition_by_fields: list[str] | None = Field(
73
+ default=None,
74
+ validation_alias="partitionByFields",
75
+ serialization_alias="partitionByFields",
76
+ description="Fields to partition by",
77
+ )
78
+
79
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
80
+ result: dict[str, Any] = {"field": self.field, "range": self.range}
81
+ if self.partition_by_fields is not None:
82
+ result["partitionByFields"] = self.partition_by_fields
83
+ return {"$densify": result}
84
+
85
+
86
+ class Fill(BaseModel):
87
+ """
88
+ $fill stage - fills null/missing field values.
89
+
90
+ Example:
91
+ >>> Fill(
92
+ ... sort_by={"date": 1},
93
+ ... output={
94
+ ... "score": {"method": "linear"},
95
+ ... "bootcamp": {"value": "missing"}
96
+ ... }
97
+ ... ).model_dump()
98
+ """
99
+
100
+ model_config = ConfigDict(populate_by_name=True, extra="forbid")
101
+
102
+ output: dict[str, Any] = Field(
103
+ ..., description="Output field specifications"
104
+ )
105
+ partition_by: str | dict[str, Any] | None = Field(
106
+ default=None,
107
+ validation_alias="partitionBy",
108
+ serialization_alias="partitionBy",
109
+ description="Partitioning expression",
110
+ )
111
+ partition_by_fields: list[str] | None = Field(
112
+ default=None,
113
+ validation_alias="partitionByFields",
114
+ serialization_alias="partitionByFields",
115
+ description="Fields to partition by",
116
+ )
117
+ sort_by: dict[str, Literal[-1, 1]] | None = Field(
118
+ default=None,
119
+ validation_alias="sortBy",
120
+ serialization_alias="sortBy",
121
+ description="Sort specification",
122
+ )
123
+
124
+ def model_dump(self, **kwargs: Any) -> dict[str, Any]:
125
+ result: dict[str, Any] = {"output": self.output}
126
+ if self.partition_by is not None:
127
+ result["partitionBy"] = self.partition_by
128
+ if self.partition_by_fields is not None:
129
+ result["partitionByFields"] = self.partition_by_fields
130
+ if self.sort_by is not None:
131
+ result["sortBy"] = self.sort_by
132
+ return {"$fill": result}
133
+
134
+
135
+ __all__ = [
136
+ "SetWindowFields",
137
+ "Densify",
138
+ "Fill",
139
+ ]
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: mongo-aggro
3
+ Version: 0.2.2
4
+ Summary: MongoDB Aggregation Pipeline Builder with Pydantic
5
+ Project-URL: Homepage, https://github.com/hamedghenaat/mongo-aggro
6
+ Project-URL: Repository, https://github.com/hamedghenaat/mongo-aggro
7
+ Project-URL: Documentation, https://hamedghenaat.github.io/mongo-aggro/
8
+ Author: Hamed Ghenaat
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: aggregation,database,mongodb,pipeline,pydantic
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Database
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.12
22
+ Requires-Dist: pydantic>=2.10.0
23
+ Provides-Extra: build
24
+ Requires-Dist: build>=1.2.0; extra == 'build'
25
+ Requires-Dist: twine>=6.0.0; extra == 'build'
26
+ Provides-Extra: dev
27
+ Requires-Dist: black>=24.10.0; extra == 'dev'
28
+ Requires-Dist: isort>=5.13.2; extra == 'dev'
29
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
30
+ Requires-Dist: pre-commit>=4.0.0; extra == 'dev'
31
+ Requires-Dist: pyupgrade>=3.19.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
33
+ Provides-Extra: docs
34
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
35
+ Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
36
+ Requires-Dist: mkdocstrings-python>=1.12.0; extra == 'docs'
37
+ Requires-Dist: mkdocstrings>=0.27.0; extra == 'docs'
38
+ Provides-Extra: test
39
+ Requires-Dist: pytest-cov>=6.0.0; extra == 'test'
40
+ Requires-Dist: pytest-mock>=3.14.0; extra == 'test'
41
+ Requires-Dist: pytest>=8.0.0; extra == 'test'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # Mongo Aggro
45
+
46
+ A Python package for building MongoDB aggregation pipelines with Pydantic.
47
+
48
+ [![PyPI](https://img.shields.io/pypi/v/mongo-aggro)](https://pypi.org/project/mongo-aggro/)
49
+ [![Python](https://img.shields.io/pypi/pyversions/mongo-aggro)](https://pypi.org/project/mongo-aggro/)
50
+ [![License](https://img.shields.io/pypi/l/mongo-aggro)](https://github.com/hamedghenaat/mongo-aggro/blob/main/LICENSE)
51
+
52
+ ## Features
53
+
54
+ - **Type-safe** - Pydantic models with full type hints
55
+ - **Zero-conversion** - Pass `Pipeline` directly to `collection.aggregate()`
56
+ - **Python operators** - Use `F("age") > 18` instead of `{"$gt": ["$age", 18]}`
57
+ - **149 expression operators** - Arithmetic, string, date, array, and more
58
+ - **46 aggregation stages** - All major MongoDB stages supported
59
+ - **31 query predicates** - Comparison, logical, geospatial, bitwise
60
+ - **17 accumulators** - Sum, Avg, Min, Max, Push, TopN, etc.
61
+
62
+ ## Installation
63
+
64
+ ```bash
65
+ uv add mongo-aggro
66
+ # or
67
+ pip install mongo-aggro
68
+ ```
69
+
70
+ ## Quick Start
71
+
72
+ ```python
73
+ from mongo_aggro import Pipeline, Match, Group, Sort, Expr
74
+ from mongo_aggro.expressions import F
75
+
76
+ # Traditional approach
77
+ pipeline = Pipeline([
78
+ Match(query={"status": "active"}),
79
+ Group(id="$category", accumulators={"total": {"$sum": "$amount"}}),
80
+ Sort(fields={"total": -1})
81
+ ])
82
+
83
+ # Python operator syntax
84
+ pipeline = Pipeline([
85
+ Match(query=Expr(expression=(F("status") == "active")).model_dump()),
86
+ Group(id="$category", accumulators={"total": {"$sum": "$amount"}}),
87
+ ])
88
+
89
+ # Pass directly to MongoDB
90
+ results = collection.aggregate(pipeline)
91
+ ```
92
+
93
+ ## Package Structure
94
+
95
+ ```python
96
+ # Import from root (most common)
97
+ from mongo_aggro import Pipeline, Match, Group, Sort, Expr
98
+
99
+ # Import expressions from sub-package
100
+ from mongo_aggro.expressions import F, AddExpr, ConcatExpr, CondExpr
101
+
102
+ # Import stages by category
103
+ from mongo_aggro.stages import Match, Project, Lookup, SetWindowFields
104
+
105
+ # Import query operators
106
+ from mongo_aggro.operators import In, Regex, GeoWithin, Exists
107
+ ```
108
+
109
+ ## Expression Operators with Python Syntax
110
+
111
+ ```python
112
+ from mongo_aggro import Expr, Match
113
+ from mongo_aggro.expressions import F
114
+
115
+ # Comparison operators
116
+ F("age") > 18 # {"$gt": ["$age", 18]}
117
+ F("status") == "active" # {"$eq": ["$status", "active"]}
118
+
119
+ # Logical operators (use & | ~ instead of and or not)
120
+ (F("age") >= 18) & (F("status") == "active")
121
+ (F("type") == "premium") | (F("balance") > 1000)
122
+
123
+ # Use in Match stage
124
+ Match(query=Expr(expression=(
125
+ (F("status") == "active") & (F("age") > 18)
126
+ )).model_dump())
127
+ ```
128
+
129
+ ## Stages
130
+
131
+ | Category | Stages |
132
+ |----------|--------|
133
+ | **Core** | Match, Project, Group, Sort, Limit, Skip, Unwind, AddFields, Set, Unset |
134
+ | **Join** | Lookup, GraphLookup, UnionWith |
135
+ | **Aggregation** | Bucket, BucketAuto, Facet, SortByCount, Count |
136
+ | **Output** | Out, Merge |
137
+ | **Window** | SetWindowFields, Densify, Fill |
138
+ | **Geospatial** | GeoNear |
139
+ | **Search** | Search, SearchMeta, VectorSearch, RankFusion |
140
+ | **Change Stream** | ChangeStream, ChangeStreamSplitLargeEvent |
141
+ | **Admin** | CollStats, IndexStats, CurrentOp, ListSessions |
142
+
143
+ ## Expression Operators
144
+
145
+ | Category | Examples |
146
+ |----------|----------|
147
+ | **Comparison** | Eq, Ne, Gt, Gte, Lt, Lte, Cmp |
148
+ | **Logical** | And, Or, Not |
149
+ | **Arithmetic** | Add, Subtract, Multiply, Divide, Mod, Abs, Ceil, Floor |
150
+ | **String** | Concat, Split, ToLower, ToUpper, Trim, RegexMatch |
151
+ | **Array** | ArraySize, Filter, Map, Reduce, Slice, InArray |
152
+ | **Date** | DateAdd, DateDiff, DateToString, Year, Month, Day |
153
+ | **Type** | ToDate, ToString, ToInt, Convert, Type |
154
+ | **Conditional** | Cond, IfNull, Switch |
155
+ | **Set** | SetUnion, SetIntersection, SetDifference |
156
+ | **Window** | Rank, DenseRank, Shift, ExpMovingAvg |
157
+
158
+ ## Query Predicates
159
+
160
+ ```python
161
+ from mongo_aggro import Match, In, Regex, Exists, GeoWithin
162
+
163
+ Match(query={
164
+ "status": In(values=["active", "pending"]).model_dump(),
165
+ "email": Regex(pattern="@company\\.com$").model_dump(),
166
+ "profile": Exists(exists=True).model_dump(),
167
+ })
168
+ ```
169
+
170
+ ## Accumulators
171
+
172
+ ```python
173
+ from mongo_aggro import Group, Sum, Avg, Max, Push, merge_accumulators
174
+
175
+ Group(
176
+ id="$category",
177
+ accumulators=merge_accumulators(
178
+ Sum(name="total", field="amount"),
179
+ Avg(name="average", field="price"),
180
+ Max(name="highest", field="price"),
181
+ )
182
+ )
183
+ ```
184
+
185
+ ## Documentation
186
+
187
+ - [User Guide](https://hamedghenaat.github.io/mongo-aggro/guide/)
188
+ - [API Reference](https://hamedghenaat.github.io/mongo-aggro/api/)
189
+ - [Examples](https://hamedghenaat.github.io/mongo-aggro/examples/)
190
+
191
+ ## License
192
+
193
+ MIT
@@ -0,0 +1,49 @@
1
+ mongo_aggro/__init__.py,sha256=pEKMZyNaS1tawDb0cTc0AA1ztWJiFL2cS-rwx754ErU,11057
2
+ mongo_aggro/accumulators.py,sha256=Q5e_iyuHvy-zxSSXgRv00VNq5zz3ku41yFIQ6FOLb74,14828
3
+ mongo_aggro/base.py,sha256=UImOK0KD12qAouYKKiFwF0gBq8Cduvmm7p08Bs1Rky0,7198
4
+ mongo_aggro/expressions/__init__.py,sha256=S99sz-fFzZCguI3viFQondR_mYSZaxsn0zlBL0w_e_s,7925
5
+ mongo_aggro/expressions/arithmetic.py,sha256=pJ_JU04uImK5AVul0YrcnXqaPRn4UxB_gCyBUegzlm0,7705
6
+ mongo_aggro/expressions/array.py,sha256=0_xAkBEA-lTVLzWP0e8BNOUIvYRpuaqPhgEncD_BVI4,10722
7
+ mongo_aggro/expressions/base.py,sha256=KHMKsYzcwbAHmMFhSVPvuXIODTgRVrdMsyV0dUmicuU,5381
8
+ mongo_aggro/expressions/bitwise.py,sha256=KR5pQc-foDu-3R8pGPUsDaKT_hR2JZItnBc927QyQDs,1979
9
+ mongo_aggro/expressions/comparison.py,sha256=IPKuAA2DuWtFgJ3JhCNZYhWv31eqPVFELBfLsP4Opog,3628
10
+ mongo_aggro/expressions/conditional.py,sha256=wVDgsUKtsKUiOAVrydNxOSavXsbkCxkAWTB-wfoIj2E,2961
11
+ mongo_aggro/expressions/date.py,sha256=Y6qpxH19p8Jp9IzMC-FcF4W2m_3P3O0wS9OaR8mk81U,18725
12
+ mongo_aggro/expressions/encrypted.py,sha256=darNTAu_QXesBY7u84e2kGyMMqiY-Y2PaRJO1kC1AFE,3315
13
+ mongo_aggro/expressions/logical.py,sha256=WcvfIaabBOpXyfxv1l3g5QvDX5Ek5H2Jl4lRaRCNhvE,1758
14
+ mongo_aggro/expressions/object.py,sha256=r6-igAHLvM7uNgHMFxqrI2K60-eV1Gr1qH_BmIMDT_k,3236
15
+ mongo_aggro/expressions/set.py,sha256=eKuOMN63uv3t605wI955FmiJ3uuwfcr7_GWbuPs33CU,3976
16
+ mongo_aggro/expressions/size.py,sha256=HdKwKQFp3wJRE8Y_0B6KRrO6ExEs2ncoYfU-AfbfDqQ,1144
17
+ mongo_aggro/expressions/string.py,sha256=hWT3Nc7G_X5h1WFKlpCP8tefXzXYNIjevgYuQILhlTI,9412
18
+ mongo_aggro/expressions/trigonometry.py,sha256=oGAeB0EHVqd4XgaWDWT16Jyu70D7TGjrRgv8hs7i1WY,6583
19
+ mongo_aggro/expressions/type.py,sha256=9Wkir3L4KIbNBa0WU1Nswqg77ZMjZAvlNk5qTLU0tIo,5043
20
+ mongo_aggro/expressions/variable.py,sha256=W5gO3gKKIuVtvNbAJEdUz9l6fqoVkQsAK00oQYBewrI,1756
21
+ mongo_aggro/expressions/window.py,sha256=BJY-_Q26pSifp5H06ffGQCHusHHOi4UFyu5jPmzBqIk,8582
22
+ mongo_aggro/operators/__init__.py,sha256=vBEFytD3YA68-9-XfrK2rfs23LK35-zaF7I_FsKPgLo,1289
23
+ mongo_aggro/operators/array.py,sha256=MnULX4J12_Rq-dNuVcTiy1gj6_Cp8pJfa82zUjzDPD4,1051
24
+ mongo_aggro/operators/base.py,sha256=TRFaPmOCmokt5z7DSKG6ieaEN3Do75q8msvGQKLfc-I,335
25
+ mongo_aggro/operators/bitwise.py,sha256=ouP8SoKe4qvcsOYG8ecRTc96HOA5dkjvlxRBsAR3CBs,1972
26
+ mongo_aggro/operators/comparison.py,sha256=2xeex4p0knVwUaWIFi0AU-VGv381MgrdyCG6PLicV8k,2150
27
+ mongo_aggro/operators/element.py,sha256=lYbspdyIsFhUXp26NfnP6xXfdf6Z1yKOY54RSIhoQgM,811
28
+ mongo_aggro/operators/geo.py,sha256=dhksA-ZbzA6T63iBtTOrzuDyWg01D44PnFWMfNn6IgQ,5683
29
+ mongo_aggro/operators/logical.py,sha256=qpe37VBvkDJSvwFrJG4UINOq2KaLh7P_ZUN-N5U00p4,3057
30
+ mongo_aggro/operators/misc.py,sha256=_DKOkqwZtUFkTpdVWy8uthKfB5ZIuVfAvLII-sxj9NU,3038
31
+ mongo_aggro/operators/regex.py,sha256=D4Yn7qGiIhH6yTm1F5P6lfpoRz4-Rn8w3rHDe1Jj3EU,645
32
+ mongo_aggro/stages/__init__.py,sha256=OyIr5g_1ostDHzrg-Ql_0elQ8itDYzKTr-D6rAAmmXw,2239
33
+ mongo_aggro/stages/array.py,sha256=mto_Dwvoktazs2Om5w2ahcpSCt1F9c0NSi7pqNL7VG0,2059
34
+ mongo_aggro/stages/change.py,sha256=Dkv0VNkZ7x3hmd3u1pTQFWwh8KmX-bxA_GXZr7rG-wI,3614
35
+ mongo_aggro/stages/core.py,sha256=q0InLKAa3EMHKJAaae2JmuKydc7pkKmSYbQKtdOkf8s,4310
36
+ mongo_aggro/stages/geo.py,sha256=1e7MZP_HRfziBOps37wuYEztkOKshYm5v3xax4Ahlx8,2939
37
+ mongo_aggro/stages/group.py,sha256=ug6JlmS65Bpq5hjaVQExX9WzItMBTFAytyuthR7TjrQ,4587
38
+ mongo_aggro/stages/join.py,sha256=Q77DQXfLvpmWVg6_fE4JS_maVUqfMerFD0sgvNcQGzk,6683
39
+ mongo_aggro/stages/misc.py,sha256=PMYKOJBu4sdR7umYhuWVEqcVclwIWoZSpV-Unq7Na0U,1034
40
+ mongo_aggro/stages/output.py,sha256=6lAnHcFUtVCdKQnELitd4xlO5A_zBLgjVX2EnUIek7w,3901
41
+ mongo_aggro/stages/search.py,sha256=3h5gkMOJZceUy6LM_zPUjepxUwxBiLZUWLkALftjrio,9648
42
+ mongo_aggro/stages/session.py,sha256=fb6U-aL9O-svuE_abDYNk4oJ5KF2K2u-VX1HXkicex4,3226
43
+ mongo_aggro/stages/stats.py,sha256=8UMcG00MxbfIxzFzdCXBk6tAc8VZ8fvXqNBzKgttKh8,4541
44
+ mongo_aggro/stages/transform.py,sha256=AXFIuEgjAY0aaQTEY4uNrxqH6cvkmJlkIqcVbka5Mwo,3621
45
+ mongo_aggro/stages/window.py,sha256=34fUensjsDwJr-jUI_c6PFgVqTmj6n2T2fZvKTJZG9c,4291
46
+ mongo_aggro-0.2.2.dist-info/METADATA,sha256=qx7oBKbbVvHUyw-widcti1f4YJx1zWL7WvGSv-evZhQ,6303
47
+ mongo_aggro-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
48
+ mongo_aggro-0.2.2.dist-info/licenses/LICENSE,sha256=XnrHxv3Dgf-ttUmsrNPMnQ69JLMED67bxKk3zrOdB40,1070
49
+ mongo_aggro-0.2.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.2.1
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any