MongoDB queries
bondi.mongodb.MongoCollectionRef
dataclass
Identify a MongoDB collection independently of a deployment.
References compare equal when both names match. They are immutable and hashable, so they can be dictionary keys or set members. No connection is created and collection existence is not checked.
Names are preserved exactly, including case and whitespace. Validation catches empty names and null characters; it does not implement all MongoDB server naming restrictions or guarantee that a server accepts the names.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
database
|
str
|
Nonempty database name without null characters. |
required |
collection
|
str
|
Nonempty collection name without null characters. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
Either name is not a string. |
ValueError
|
Either name is empty or contains a null character. |
Examples:
>>> target = MongoCollectionRef("research", "businesses")
>>> target.database
'research'
>>> target == MongoCollectionRef("research", "businesses")
True
>>> len({target, MongoCollectionRef("research", "businesses")})
1
Source code in src/bondi/mongodb/collection.py
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 | |
bondi.mongodb.MongoFindQuery
dataclass
Describe a MongoDB find operation without executing it.
This is a mutable, unhashable value object. Filter and projection documents
are deep-copied on construction, including nested dictionaries and lists.
Subsequent edits to those input documents do not affect this query, and vice
versa. Values must support Python's deepcopy operation.
Validation runs at construction and before serialization or fingerprinting. Later assignments and nested edits are ordinary Python mutations: they are neither validated nor defensively copied. Validation checks the outer document types and pagination/sort structure; it does not validate MongoDB operators, BSON encodability or server acceptance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
MongoCollectionRef
|
Logical collection to query, independent of a deployment. |
required |
filter
|
dict[str, Any]
|
Required predicate dictionary; use an empty dictionary explicitly to describe an unrestricted query. |
required |
projection
|
dict[str, Any] | None
|
Optional projection dictionary. None means no explicit projection. |
None
|
sort
|
tuple[tuple[str, int], ...]
|
Ordered tuple of (field name, direction) tuples. Directions must be integer 1 or -1. The empty tuple means no explicit sort. Metadata sorts are not supported by this initial interface. |
()
|
skip
|
int
|
Nonnegative integer number of results to skip. Booleans are rejected. |
0
|
limit
|
int | None
|
Positive integer result limit, or None for no limit. Zero and booleans are rejected; use None explicitly for an unlimited query. |
None
|
Raises:
| Type | Description |
|---|---|
TypeError
|
A field has an incorrect type, including a boolean used as an integer. |
ValueError
|
Pagination bounds or sort names, pair lengths or directions are invalid. |
Examples:
>>> predicate = {"stars": {"$gte": 4}}
>>> query = MongoFindQuery(MongoCollectionRef("research", "businesses"), predicate)
>>> query.filter["stars"]["$gte"] = 5
>>> predicate["stars"]["$gte"]
4
>>> query.limit = 20
>>> query.limit
20
Source code in src/bondi/mongodb/query.py
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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
fingerprint() -> str
Return the SHA-256 hex digest of the current serialized representation.
Computed on every call after validation. Includes the format version, target and all query options; preserves document order. Identifies the serialized representation, not semantic equivalence or deployment state. Raises the same errors as to_json.
Source code in src/bondi/mongodb/query.py
180 181 182 183 184 185 186 187 188 | |
from_json(text: str) -> Self
classmethod
Load a version-1 envelope produced by to_json.
Whitespace and envelope field order may differ. BSON payloads must use Canonical Extended JSON. Unknown, missing and duplicate envelope fields are rejected; duplicate document keys are also rejected at any depth.
Raises:
| Type | Description |
|---|---|
TypeError
|
Input is not a string or a decoded field has an incorrect type. |
ValueError
|
JSON, the envelope, canonical payload or field values are invalid. |
Source code in src/bondi/mongodb/query.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
to_json() -> str
Serialize a version-1 JSON envelope with a Canonical Extended JSON filter.
Metadata, projection, sort, skip and limit use ordinary JSON. Projections must contain JSON-serializable values. Preserves document and sort order. Dates normalize to millisecond precision and load as naive UTC datetimes. Binary subtype zero loads as bytes; large integers may load as bson.Int64. These preserve the serialized BSON value, not necessarily its original Python representation.
Raises:
| Type | Description |
|---|---|
TypeError
|
Structural validation or BSON-aware JSON encoding fails. |
ValueError
|
Validation fails or a document is ambiguous with an Extended JSON type wrapper. Use bson.Regex instead of a $regex/$options document. Unsupported Python values may raise codec exceptions. |
Examples:
>>> query = MongoFindQuery(MongoCollectionRef("research", "businesses"), {})
>>> MongoFindQuery.from_json(query.to_json()) == query
True
Source code in src/bondi/mongodb/query.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
validate() -> None
Check current structural constraints without modifying the query.
Raises:
| Type | Description |
|---|---|
TypeError
|
A field has an incorrect type. |
ValueError
|
A field violates the constructor's value constraints. |
BSON encoding and MongoDB operator validity are not checked here.
Source code in src/bondi/mongodb/query.py
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 | |
bondi.mongodb.MongoAggregateQuery
dataclass
Describe a collection-based aggregation without executing it.
Mutable and unhashable. The pipeline is deep-copied at construction. Later assignments and nested edits are neither copied nor automatically validated. Validation runs at construction, explicitly, and before serialization or fingerprinting. Only top-level stage structure is checked; stage semantics and nested pipelines are left to MongoDB. Write stages such as $out and $merge are representable: this class does not promise read-only execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
MongoCollectionRef
|
Starting collection, independent of a deployment. References to additional collections remain in the native pipeline. |
required |
pipeline
|
list[dict[str, Any]]
|
Required ordered list of single-key stage dictionaries. An empty list is allowed. Each key must start with $ and contain a name after it. Values may be scalars, documents or arrays; their semantics are not checked. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
Target, pipeline, a stage or a stage key has an incorrect type. |
ValueError
|
A stage has other than one key or an invalid stage-name prefix. |
Examples:
>>> stages = [{"$match": {"stars": {"$gte": 4}}}, {"$limit": 10}]
>>> query = MongoAggregateQuery(MongoCollectionRef("research", "businesses"), stages)
>>> query.pipeline[1]["$limit"] = 5
>>> stages[1]["$limit"]
10
>>> restored = MongoAggregateQuery.from_json(query.to_json())
>>> restored.fingerprint() == query.fingerprint()
True
Source code in src/bondi/mongodb/aggregate.py
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 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
fingerprint() -> str
Compute SHA-256 of the current serialized representation after validation.
Includes version, kind, target and pipeline; preserves stage and document order. Recomputed on every call. Does not identify semantic equivalence or deployment state. Raises the same errors as to_json.
Source code in src/bondi/mongodb/aggregate.py
128 129 130 131 132 133 134 135 | |
from_json(text: str) -> Self
classmethod
Load a version-1 aggregation envelope with a canonical BSON pipeline.
Allows whitespace and envelope-field reordering. Rejects unknown versions, wrong query kinds, missing/extra fields and duplicate JSON keys at any depth.
Raises:
| Type | Description |
|---|---|
TypeError
|
Input or decoded query fields have incorrect types. |
ValueError
|
Invalid JSON, envelope, pipeline structure or noncanonical payload. |
Source code in src/bondi/mongodb/aggregate.py
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
to_json() -> str
Serialize a validated version-1 mongodb.aggregate envelope.
Uses ordinary JSON metadata and a Canonical Extended JSON pipeline, preserving stage and document order. Shares find-query BSON normalization: dates load as naive UTC with millisecond precision, binary subtype zero as bytes, and large integers may become bson.Int64. Literal documents ambiguous with Extended JSON wrappers are rejected. Serialization does not modify the query.
Raises:
| Type | Description |
|---|---|
TypeError
|
Structural validation or BSON-aware encoding fails. |
ValueError
|
Invalid structure or an ambiguous Extended JSON document. |
Unsupported values may also raise codec exceptions.
Source code in src/bondi/mongodb/aggregate.py
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 | |
validate() -> None
Check current target and top-level stage structure without mutation.
Raises:
| Type | Description |
|---|---|
TypeError
|
Target, pipeline, stage or stage key has an incorrect type. |
ValueError
|
A stage does not have exactly one $-prefixed nonempty name. |
Does not validate stage arguments, supported operators, nested pipelines, BSON encodability or whether a pipeline writes data.
Source code in src/bondi/mongodb/aggregate.py
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 | |