Skip to content

Commit 9016184

Browse files
authored
Merge pull request #49 from linkml/mongo-select
Allowing paths to be used for select queries with mongodb
2 parents 5fbc6a7 + 3dc3a22 commit 9016184

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

src/linkml_store/api/stores/mongodb/mongodb_collection.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from linkml_store.api import Collection
88
from linkml_store.api.collection import DEFAULT_FACET_LIMIT, OBJECT
99
from linkml_store.api.queries import Query, QueryResult
10+
from linkml_store.utils.object_utils import object_path_get
1011

1112
logger = logging.getLogger(__name__)
1213

@@ -130,7 +131,15 @@ def upsert(
130131
def query(self, query: Query, limit: Optional[int] = None, offset: Optional[int] = None, **kwargs) -> QueryResult:
131132
mongo_filter = self._build_mongo_filter(query.where_clause)
132133
limit = limit or query.limit
133-
cursor = self.mongo_collection.find(mongo_filter)
134+
135+
# Build projection if select_cols are provided
136+
projection = None
137+
if query.select_cols:
138+
projection = {"_id": 0}
139+
for col in query.select_cols:
140+
projection[col] = 1
141+
142+
cursor = self.mongo_collection.find(mongo_filter, projection)
134143
if limit and limit >= 0:
135144
cursor = cursor.limit(limit)
136145
offset = offset or query.offset
@@ -141,9 +150,19 @@ def query(self, query: Query, limit: Optional[int] = None, offset: Optional[int]
141150

142151
def _as_row(row: dict):
143152
row = copy(row)
144-
del row["_id"]
153+
if "_id" in row:
154+
del row["_id"]
155+
145156
if select_cols:
146-
row = {k: row[k] for k in select_cols if k in row}
157+
# For nested fields, ensure we handle them properly
158+
result = {}
159+
for col in select_cols:
160+
# If it's a nested field (contains dots)
161+
if "." in col or "[" in col:
162+
result[col] = object_path_get(row, col)
163+
elif col in row:
164+
result[col] = row[col]
165+
return result
147166
return row
148167

149168
rows = [_as_row(row) for row in cursor]

src/linkml_store/utils/object_utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,21 @@ def object_path_get(obj: Union[BaseModel, Dict[str, Any]], path: str, default_va
8383
'NA'
8484
"""
8585
if isinstance(obj, BaseModel):
86-
obj = obj.dict()
86+
obj = obj.model_dump()
8787
parts = path.split(".")
8888
for part in parts:
8989
if "[" in part:
9090
key, index = part[:-1].split("[")
9191
index = int(index)
92-
obj = obj[key][index]
92+
if key in obj and obj[key] is not None:
93+
obj = obj[key][index]
94+
else:
95+
return default_value
9396
else:
94-
obj = obj.get(part, default_value)
97+
if isinstance(obj, list):
98+
obj = [v1.get(part, default_value) for v1 in obj]
99+
else:
100+
obj = obj.get(part, default_value)
95101
return obj
96102

97103

0 commit comments

Comments
 (0)