We have a large Revit model uploaded (~4 GB total), and have a list of 30-40 Revit element IDs we are trying to find in the viewer and select on screen, then create a section box around.
We have tried to create a map of all elements and dbids, then search through it - but this is taking 2-3 minutes for the model to create, then more time to search through.
We've also tried to use the Model Derivative API to search for the elements, but it seems that the dbid is only generated in the viewer. So we can get properties and locations to create the section box, but cannot select them in the model.
Finally we tried using the search function in the viewer, but it only accepts one argument at a time, so searching for each element id, then getting a dbid, across 40 searches is taking some time.
Is there a way to search in the viewer based on multiple paramaters, like an AND / OR function?
I assume you've been using getExternalIdMapping
to search for your elements. If this takes multiple minutes I have a possible solutions which will be quite a bit of work but could significantly speed up your queries.
I believe the dbId <-> externalId mapping can also be extracted from the PropertyDatabase
, a SQLite db you can download. This blog post outlines how to download and process the db but is slightly out of date. These are the steps I use:
role: Autodesk.CloudPlatform.PropertyDatabase
The db will probably be about the same size as your Revit Model. Running live queries on this large db will not be very fast but still a lot faster than searching in the frontend. If you need more performance you'll need to extract the minimal required information to satisfy your queries from the db upfront and hold it in memory (or Redis). I think this should easily give you subsecond response times and is only limited by the amount of memory available to your backend.
Update
I tested this with SVF2 models and realized that the dbIds in the SQLite database do not match the dbIds in the viewer. I assume these ids are for the older SVF format. A workaround is to query the database for externalId
and then looking up the viewer dbId using this APS (Beta) endpoint. You might be able to skip the database completely if this endpoint supports the queries you want to run. See Update 2 for another option to map dbIds.
APS properties:query caveats
The api endpoint is currently (Q1 2023) in beta and on the reference page it says DO NOT USE IN PRODUCTION ENVIRONMENTS
¯\_(ツ)_/¯
I tested it by mapping the externalIds of ~800 rooms to their corresponding (SVF2) dbIds in a single request with the following query:
{
"query": {
"$in": [
"externalId",
"3e22bf41-f3f7-4cc9-89fe-abc441902d17-00373b62",
"3e22bf41-f3f7-4cc9-89fe-abc441902d17-00373b6b",
"3e22bf41-f3f7-4cc9-89fe-abc441902d17-00373b6c",
...
]
},
"fields": ["objectid"],
"pagination": { "limit": 1000, "offset": 0 }
}
The response time for this request was about 500ms to 1 second.
Currently the api returns { "result": "success" }
instead of actual data a lot, almost on every other request. Immediately retrying seems to work fine.
Update 2 (more on SVF to SVF2 id mapping)
After some more searching I found this excellent answer by Cyrille https://stackoverflow.com/a/68453416/2025261 including links to his sample implementation: fetching the id array and decoding it. This is extremely efficient since lookups are just index operations on this array, eg. array[svfId] === svf2Id
.