Skip to content

Commit 49da7ab

Browse files
authored
Merge pull request #58 from linkml/llm-indexing
Add comprehensive LLM indexing, embedding utilities, and visualization features
2 parents 2a81477 + ab4fd30 commit 49da7ab

36 files changed

+217835
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ tests/input/integration/
66
tmp/
77
*.TEST-RUN.ipynb
88
*.tmp
9+
docs/how-to/output/
910

1011

1112
# Byte-compiled / optimized / DLL files

CONTRIBUTING.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,161 @@ and make your changes on a [new branch][about-branches].
5050
[pulls]: https://github.com/linkml/linkml-store/pulls/
5151

5252
We recommend also reading [GitHub Pull Requests: 10 Tips to Know](https://blog.mergify.com/github-pull-requests-10-tips-to-know/)
53+
54+
## Adding a New Backend Store
55+
56+
LinkML-Store supports multiple backend stores (databases) through a common abstraction layer. To add support for a new backend, follow these steps:
57+
58+
### 1. Create the Backend Module Structure
59+
60+
Create a new directory under `src/linkml_store/api/stores/` for your backend:
61+
62+
```
63+
src/linkml_store/api/stores/mybackend/
64+
__init__.py
65+
mybackend_database.py
66+
mybackend_collection.py
67+
```
68+
69+
### 2. Implement the Database Class
70+
71+
Create a database class that inherits from `linkml_store.api.Database`:
72+
73+
```python
74+
from linkml_store.api import Database
75+
from .mybackend_collection import MyBackendCollection
76+
77+
class MyBackendDatabase(Database):
78+
collection_class = MyBackendCollection
79+
80+
def __init__(self, handle: Optional[str] = None, **kwargs):
81+
super().__init__(handle=handle, **kwargs)
82+
# Initialize your backend connection here
83+
84+
def commit(self, **kwargs):
85+
# Implement transaction commit
86+
pass
87+
88+
def close(self, **kwargs):
89+
# Close backend connection
90+
pass
91+
92+
def drop(self, missing_ok=True, **kwargs):
93+
# Drop the database
94+
pass
95+
96+
def list_collection_names(self) -> List[str]:
97+
# Return list of collection names
98+
pass
99+
```
100+
101+
### 3. Implement the Collection Class
102+
103+
Create a collection class that inherits from `linkml_store.api.Collection`:
104+
105+
```python
106+
from linkml_store.api import Collection
107+
from linkml_store.api.queries import Query, QueryResult
108+
109+
class MyBackendCollection(Collection):
110+
def insert(self, objs: Union[OBJECT, List[OBJECT]], **kwargs):
111+
# Insert objects into the collection
112+
pass
113+
114+
def delete(self, objs: Union[OBJECT, List[OBJECT]], **kwargs) -> Optional[int]:
115+
# Delete objects from the collection
116+
pass
117+
118+
def query(self, query: Query, **kwargs) -> QueryResult:
119+
# Execute a query and return results
120+
pass
121+
122+
def find(self, where: Optional[Dict[str, Any]] = None, **kwargs) -> QueryResult:
123+
# Find objects matching criteria
124+
pass
125+
126+
def update(self, objs: Union[OBJECT, List[OBJECT]], **kwargs):
127+
# Update existing objects
128+
pass
129+
```
130+
131+
### 4. Register the Backend
132+
133+
Add your backend to the `HANDLE_MAP` in `src/linkml_store/api/client.py`:
134+
135+
```python
136+
HANDLE_MAP = {
137+
# ... existing backends ...
138+
"mybackend": "linkml_store.api.stores.mybackend.mybackend_database.MyBackendDatabase",
139+
}
140+
```
141+
142+
If your backend uses file extensions, add them to `SUFFIX_MAP`:
143+
144+
```python
145+
SUFFIX_MAP = {
146+
# ... existing suffixes ...
147+
"mdb": "mybackend:///{path}",
148+
}
149+
```
150+
151+
### 5. Add Dependencies
152+
153+
If your backend requires additional dependencies, add them to `pyproject.toml`:
154+
155+
```toml
156+
[tool.poetry.extras]
157+
mybackend = ["mybackend-python-client>=1.0.0"]
158+
all = [
159+
# ... existing dependencies ...
160+
"mybackend-python-client>=1.0.0",
161+
]
162+
```
163+
164+
### 6. Write Tests
165+
166+
Create test files in the `tests/` directory:
167+
168+
```python
169+
# tests/test_stores/test_mybackend.py
170+
import pytest
171+
from linkml_store import Client
172+
173+
def test_mybackend_basic_operations():
174+
client = Client()
175+
db = client.attach_database("mybackend:///:memory:", alias="test")
176+
collection = db.create_collection("TestCollection")
177+
178+
# Test insert
179+
collection.insert([{"id": "1", "name": "Test"}])
180+
181+
# Test query
182+
result = collection.find()
183+
assert len(result.rows) == 1
184+
assert result.rows[0]["name"] == "Test"
185+
```
186+
187+
### 7. Document Your Backend
188+
189+
Add documentation explaining:
190+
- Connection string format (e.g., `mybackend://host:port/database`)
191+
- Any special configuration options
192+
- Limitations or backend-specific features
193+
- Example usage in notebooks
194+
195+
### Best Practices
196+
197+
1. **Handle Errors Gracefully**: Provide clear error messages for connection failures and unsupported operations
198+
2. **Type Mapping**: Implement proper type mapping between LinkML types and your backend's native types
199+
3. **Performance**: Consider implementing batch operations for better performance
200+
4. **Schema Support**: If your backend supports schemas, integrate with LinkML's schema validation
201+
5. **Indexing**: Implement index creation/management if supported by your backend
202+
6. **Query Translation**: Convert LinkML queries to your backend's query language
203+
204+
### Example Backends to Study
205+
206+
Look at these existing implementations for reference:
207+
- `duckdb`: SQL-based backend with array support
208+
- `mongodb`: Document-based NoSQL backend
209+
- `filesystem`: File-based storage using JSON/YAML/CSV files
210+
- `neo4j`: Graph database backend

docs/explanation/index.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.. explanation:
2+
:title: LinkML-Store Explanations
3+
4+
Explanation
5+
===========
6+
7+
Understanding concepts and architecture in LinkML-Store.
8+
9+
.. toctree::
10+
:maxdepth: 3
11+
:caption: Contents:
12+
13+
indexing-architecture

0 commit comments

Comments
 (0)