Using the Document Store
This page explains everything you need to know when developing a Cloud Function that makes use of the Document Store.
What is the Document Store?
A Document Store is a database that can store data that you would want your Cloud Function to keep over time. For example, if you want your Cloud Function to register and store what actions each user takes, you could store this in the document store. Each Cloud Function has its own separate store and can only read and write data to its own store. A Cloud Function can only access a single store. The document store can accept any data in JSON format. This means that if you store documents in the store, you must ensure that your data can be converted to JSON.
A local document store is automatically provided for you when you develop your Cloud Function.
Store Availability
- The store isn't available from the developer web form.
- When developing the local store is reset at each restart.
- The store is only available from
ixoncdkingress>=0.0.10
When starting your Cloud Function, you should see the following messages:
ixoncdkingress - INFO - Starting DocumentDB server
ixoncdkingress - INFO - DocumentDB server started successfully
These messages show that the document store has successfully started and can be used in your Cloud Function.
How to use the DocumentDBClient
The DocumentDBClient
can be extracted from the Cloud Function Context by accessing document_db_client
from the context:
from ixoncdkingress.function.context import FunctionContext
@FunctionContext.expose
def document_test_entrypoint(context: FunctionContext):
print(context.document_db_client)
From here you can perform a variety of functions to create, read, update and delete documents in your document store.
Nullability
As mentioned above, the store is not always available. So the
document_db_client
can beNone
. Be sure to check for this when developing your Cloud Function.
Timezones
All dates, times and datetimes will be returned as naive objects (i.e. unaware of timezone) by the DocumentDBClient. All times and datetimes are stored in UTC and should be interpreted as such. When storing times and datetimes in Document Store, always use UTC.
The DocumentDBClient
contains the following functions:
Function | Parameters | Description | Minimal ixoncdkingress version |
---|---|---|---|
insert_one | document: Dict | Inserts a single document into the store | 0.0.10 |
insert_many | document: Iterable[Dict] | Inserts multiple documents into the store | 0.0.10 |
update_one | filter_map: Mapping, update: Mapping | Updates a single document from the store | 0.0.10 |
update_many | filter_map: Mapping, update: Mapping | Updates multiple documents from the store | 0.0.10 |
delete_one | filter_map: Mapping | Removes one document from the store | 0.0.10 |
delete_many | filter_map: Mapping | Removes multiple documents from the store | 0.0.10 |
find_one | filter_map: Mapping | Same as find but only returns a single document | 0.0.10 |
find | filter_map: Mapping | Perform a query on the database with a specific filter | 0.0.10 |
switch_collection | collection_name: Optional[str] | Switch to another collection. When collection_name is None or an empty string, the default collection is used | 0.0.17 |
Multiple collections
The document store has one collection by default. When you want to use multiple collections, please send an email to [email protected] to have them configured and provide the following details:
- The Cloud Function public ID.
- The name(s) of the collection(s) you want to use.
The filter_map
can be used to find specific documents by their keys, while the update
Mapping can be used to update specific keys of one or more documents. Here is an example of some of the functions you can use:
from typing import Any, List, TypedDict
from bson.json_util import dumps
from ixoncdkingress.function.context import FunctionContext
@FunctionContext.expose
def document_find_text(context: FunctionContext, id: int) -> dict[str, Any] | None:
# Find one document by its ID
return dumps(context.document_db_client.find_one(filter_map={'id': id}))
@FunctionContext.expose
def document_find_all(context: FunctionContext) -> str:
# Find all documents in the store
return dumps(context.document_db_client.find())
@FunctionContext.expose
def document_add_or_update_text(context: FunctionContext, id: int, text: str) -> None:
found = document_find_text(context, id)
# If document already exists update the text by the ID
# otherwise insert a new document
if found is not None:
context.document_db_client.update_one({'id': id}, {'$set': {'text': text}})
else:
context.document_db_client.insert_one({'id': id, 'text': text})
class Document(TypedDict):
id: int
text: str
@FunctionContext.expose
def document_insert_many(context: FunctionContext, documents: List[Document]) -> None:
# Insert the documents
context.document_db_client.insert_many(documents)
<script>
import { onMount } from "svelte";
export let context; // Assuming context is passed in as a prop for backend interactions
let client; // Initialize the client for backend communication
// Modular function to call backend functions
async function callBackendFunction(functionName, parameters = {}) {
try {
const response = await client.call(functionName, parameters);
console.log(response);
return response; // Return response for further processing
} catch (error) {
console.error(`Error calling ${functionName}:`, error);
}
}
onMount(() => {
client = context.createBackendComponentClient();
// Sequentially call backend functions with await inside async function
(async () => {
await callBackendFunction("functions.document_find_all");
await callBackendFunction("functions.document_add_or_update_text", {
id: 0, // Example ID, ensuring it's an integer to match Python backend
text: "Hello, World!",
});
await callBackendFunction("functions.document_find_all");
await callBackendFunction("functions.document_find_text", {
id: 0,
});
await callBackendFunction("functions.document_insert_many", {
documents: [
{ id: 1, text: "First text" },
{ id: 2, text: "Second text" },
],
});
await callBackendFunction("functions.document_find_all");
})();
});
</script>
<main>
<h1>Frontend Component</h1>
<p>Open the terminal to see the results of the backend calls.</p>
</main>
From here, you can play around with inserting, reading, updating and deleting documents.
Inspecting the Document Store contents
You can easily inspect the contents of you local Document Store using MongoDB Compass GUI or MongoDB For VS Code.
Updated 3 days ago
To read more about advanced document querying please read: