beanie
beanie copied to clipboard
Query linked fields
Hi there,
I have two documents a build and a deployment. A deployment has a build parameter that is a Link to a build document. Multiple deployments can be linked to the same build.
I now have two requirements:
- Get a list of all deployments for a build (the build _id is supplied)
- Get a list of all deployments that have a build where the project_name equals xyz.
I couldn't find any relevant sections in the docs.
Is this something Beanie has support for?
Hi @joe-fitkey ,
- You can find by id with the next query:
from beanie import Document, Link
class Build(Document):
...
class Deployment(Document):
build: Link[Build]
...
build_id = "YOUR BUILD ID"
deployments = await Deployment.find({"build.$id": build_id}).to_list()
$
there is not a typo. It uses RefID field type inside.
I plan to add backward linking and syntax sugar for this find query later.
- Unfortunately, this is possible with lookup aggregations only for now. Here is the MongoDB doc for lookups: https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/ Here is the Beanie doc for aggregations: https://roman-right.github.io/beanie/tutorial/aggregation/
Find by fields of the linked documents is one of the most important features to develop for now. It is estimated to be done in 2-3 weeks. I'll inform you here when it will be done.
Seems like there was an initial go at getting this working recently. But the documented approach doesn't seem to work for me.
Using the above example my code would be something like
Deployment.find(Deployment.build.id == build_id, fetch_links=True)
This doesn't seem to work. I've tried what you mentioned as well with the {"build.$id": build_id}
however this only works if you do NOT specify fetch_links
The docs claim that this works but I also find that it does not
Okay, I spent some more time with this, and it does seem to be the case that the documented behavior is not accurate. I am unable to query for a document by the properties of it DbRef, despite this apparently being supported. Any ideas as to why? My setup is basically:
# the base classes just define properties shared with the API schema objects
class Device(Document, DeviceBase):
name: Optional[str] = ""
class Package(Document, PackageBase):
tracking_number: Indexed(str, unique=True) # type: ignore
device: Link[Device]
device_ids = ['id1', 'id2', 'id3']
packages = await Package.
In(Package.device.id, device_ids),
fetch_links=True,
).to_list()
# packages returns []
# I've also tried i.e.:
packages = await Package.
Package.device.id == 'id1',
fetch_links=True,
).to_list()
packages = await Package.
Package.device.id == Device1.id,
fetch_links=True,
).to_list()
packages = await Package.
Package.device == Device1,
fetch_links=True,
).to_list()
This issue is stale because it has been open 30 days with no activity.
This issue was closed because it has been stalled for 14 days with no activity.
same issue here.
This works
app = await App.get(str(app_id))
# check if app exists
query = await QueryDoc.find({ "app.$id": app_id}).to_list(limit)
but these don't
query = await QueryDoc.find(QueryDoc.app == app.id).to_list(limit)
query = await QueryDoc.find(QueryDoc.app == app).to_list(limit)