art049 / art049/odmantic

Getting OperationFailure error when trying to find using the $near operator

Open
#337 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
1.2k
Forks
97
PR merge metrics
No merged PRs in 30d

Description

# Bug

I'm getting a `pymongo.errors.OperationFailure: $geoNear, $near, and $nearSphere are not allowed in this context` error when trying to find using the [$near](https://www.mongodb.com/docs/manual/reference/operator/query/near/#mongodb-query-op.-near) operator.

### Current Behavior

If I have defined the following classes:

```python
class GeoJSON(BaseModel):
type: str = "Point"
coordinates: tuple[float, float]

class Instruction(Model):
name: str
geo_json: GeoJSON
```

And execute this query:
```python
engine.find(Instruction, {
"geo_json": {
"$near": {
"$geometry": {
"type": "Point",
"coordinates": [
-65.49250524795319,
-24.732399067642003
]
},
"$maxDistance": 500
}
}
})
```

The following exception is raised:
```python
pymongo.errors.OperationFailure: $geoNear, $near, and $nearSphere are not allowed in this context, full error: {'ok': 0.0, 'errmsg': '$geoNear, $near, and $nearSphere are not allowed in this context', 'code': 2, 'codeName': 'BadValue', '$clusterTime': {'clusterTime': Timestamp(1676945612, 1), 'signature': {'hash': b'\x8b2\xd80ipA\x82,R\x1bN\xa7a\xad\x7f\xcb\xaeI\x84', 'keyId': 7155114180230512642}}, 'operationTime': Timestamp(1676945612, 1)}
```

### Expected behavior

The query should return a list of Instructions.

### Environment

- ODMantic version: `0.9.2`
- MongoDB version: `5.0.14 (Mongo Atlas)`
- Pydantic infos (output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())`):

```
pydantic version: 1.10.5
pydantic compiled: True
install path: /usr/local/lib/python3.11/site-packages/pydantic
python version: 3.11.1 (main, Dec 23 2022, 09:39:26) [Clang 14.0.0 (clang-1400.0.29.202)]
platform: macOS-13.1-x86_64-i386-64bit
optional deps. installed: ['dotenv', 'email-validator', 'typing-extensions']

```

- Version of additional modules (if relevant):
- motor: `3.1.1`
- Python version: `Docker python:3.10-buster`

**Additional context**

In my DB i have a collection "instruction" with objects like:
```json
{
"_id": { "$oid": "63f4162924a0a5952a0904ef" },
"name": "Some name",
"geo_json":
{
"type": "Point",
"coordinates":
[
{ "$numberDouble": "-65.49250524795319" },
{ "$numberDouble": "-24.732399067642003" }
]
}
}
```
And I've added the index:
```json
{ "geo_json": "2dsphere" }
```

When I try to use the Find on Mongo Atlas, if I add this on the search field:
```json
{
"geo_json": {
"$near": {
"$geometry": {
"type": "Point",
"coordinates": [
-65.49250524795319,
-24.732399067642003
]
},
"$maxDistance": 500
}
}
}
```
It returns the object correctly.

Also, if I change the python code to this:

```python
collection = engine.get_collection(Instruction)
response = collection.find({
"geo_json": {
"$near": {
"$geometry": {
"type": "Point",
"coordinates": [
-65.49250524795319,
-24.732399067642003
]
},
"$maxDistance": 500
}
}
})
instructions = await response.to_list(length=None)
return [Instruction.parse_doc(instruction) for instruction in instructions]
```

Then the search works.

Is the find functionality not working fine or I'm just using it wrong?

Contributor guide

Open the contributing guide

Research direction

Reproduce the query through engine.find(Instruction, ...) and compare it with engine.get_collection(Instruction).find(...), which the report says succeeds. Trace how the engine path handles the $near filter and verify that it preserves the MongoDB query and returns Instruction objects; done when the reported query works without bypassing the engine.

Written by the indexing model from the issue text.

Assessment

Tech stack
mongodb, python
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.