How to Write Queries with WeaveDB

How to Write Queries with WeaveDB

Introduction

WeaveDB is a powerful database management system built on Arweave Blockchain that allows you to interact with your data using the WeaveDB SDK. In this guide, we will walk you through the process of writing queries for WeaveDB. We'll cover various query types, including set, upsert, update, and special operations, along with explanations and example code.

Prerequisites:

Before you begin, ensure that you have the WeaveDB SDK object stored in a variable called db. If you haven't initialized it, refer to the "Initialize WeaveDB" documentation.

Additionally, make sure you have the collection_name variable, which represents the name of your collection, and the doc_id variable, which contains the unique identifier of a document in your collection.

Query Types

1. Set

The set query is used to override the entire document if doc_id exists in the collection. If the doc_id does not exist, a new document is added.

await db.set({ age: 20, name: "Bob" }, collection_name, doc_id);

This query will reset the whole document if doc_id already exists.

2. Upsert

The upsert query merges the new data with an existing document or sets a new document if it doesn't exist.

await db.upsert({ age: 20, name: "Bob" }, collection_name, doc_id);

3. Update

The update query allows you to modify an existing document in the collection. This query will fail if the doc_id does not exist.

await db.update({ age: 25 }, collection_name, doc_id);

4. Add

To add a new document with a randomly yet deterministically assigned doc_id, use the add query:

await db.add({ age: 20, name: "Bob" }, collection_name);

Special Operations

WeaveDB also offers special operations that provide shortcuts for common tasks.

5. Delete a Field

To delete a field from a document, you can use the db.del() function within the update query:

await db.update({ age: db.del() }, collection_name, doc_id);

6. Increase a Field

To increase a numeric field, you can use db.inc() with a positive value:

await db.update({ age: db.inc(5) }, collection_name, doc_id);

7. Decrease a Field

To decrease a numeric field, use db.inc() with a negative value:

await db.update({ age: db.inc(-5) }, collection_name, doc_id);

8. Array Union

To perform a union operation on an array field, use db.union():

await db.update({ chars: db.union(["a", "b", "c", "d"]) }, collection_name, doc_id);

9. Array Remove

To remove specific elements from an array field, use db.remove():

await db.update({ chars: db.remove(["b", "c"]) }, collection_name, doc_id);

10. Set Block Timestamp

Use db.ts() to set the current block's timestamp to a field:

await db.update({ date: db.ts() }, collection_name, doc_id);

11. Set Signer Ethereum Address

Set an Ethereum address, ensuring it's in lowercase if it's an EVM wallet address:

await db.update({ address: db.signer() }, collection_name, doc_id);

12. Delete a Document

To delete a document from the collection, use the delete query:

await db.delete(collection_name, doc_id);

13. Batch Queries

You can perform multiple read and write operations atomically using a batch. All operations within the batch are either fully completed or completely aborted if any write operation fails.

await db.batch([
  ["set", { name: "Bob" }, "people", "Bob"],
  ["upsert", { name: "Alice" }, "people", "Alice"],
  ["delete", "John"]
]);

Note that you can use the batch feature only if all the queries are by the same signer. If you have multiple signers, use the bundle.

14. Bundle Queries

To bundle multiple queries from different signers, you can use the bundle feature:

const query1 = await db.sign("set", { name: "Bob" }, "people", "Bob", { evm: wallet1 });
const query2 = await db.sign("set", { name: "Alice" }, "people", "Alice", { ii: wallet2 });
const query3 = await db.sign("set", { name: "Beth" }, "people", "Beth", { ar: wallet3 });

await db.bundle([query1, query2, query3], { ar: bundler_wallet });

15. Sign a Query

You can sign a query without sending a transaction using the sign function:

await db.sign("set", { name: "Bob", age: 20 }, collection_name, doc_id);

16. Relay a Query

To relay a query, you can sign the query first and then relay it using the relay function:

const param = await db.sign("set", { name: "Bob" }, collection_name, doc_id);
const extra = { age: 20 };
await db.relay("jobID", param, extra, { evm: relayer_wallet });

WeaveDB gives you access to a set of query options for managing your data efficiently. Be sure to refer to the official documentation here for more details and docs guides for integration and developer support from the team.

Did you find this article valuable?

Support Gordian Etim by becoming a sponsor. Any amount is appreciated!