SurrealDB Docs Logo

Enter a search query

Using SurrealDB as a Document Database

One of the most popular models of database is the document model database. It provides a flexible way to store data, allowing for nested structures and relationships to be stored within a single document.

In a document database, data is stored in the form of documents—which usually resemble JSON objects—rather than in rows and columns.

This model offers a level of simplicity and flexibility that can be especially appealing when your data does not naturally fit into a strict tabular format or when the structure of your data frequently changes.

Over the last decade, we have seen a surge of NoSQL databases such as MongoDB, CouchDB, and DynamoDB, all of which are in the broad category of document stores (although with varying specific features).

But how do you “think” in a document model database? Thinking in a document model means orienting your data design around the entities as you naturally represent them in your applications, rather than forcing your data into normalized or heavily structured relational schemas.

For example, you have a table called users in your application, the document model database will store user data (e.g., name, age, addresses) in a single JSON-like document.

By clicking the Run query button, you will see the following result:

[ { "id": "users:a2ndbh1hsquvkvthws09", "name": "Alice Smith", "email": "alice@example.com", "age": 29, "addresses": [ { "type": "home", "address_line": "123 Maple St", "city": "Springfield", "country": "USA" }, { "type": "work", "address_line": "456 Oak Ave", "city": "Metropolis", "country": "USA" } ] } ]

You may notice that the id field has a users: prefix. This is because SurrealDB uses a id to uniquely identify each record and the combination of the table name and the record id is used as the record link.

In this guide, we will explore how to think in a document model database, in SurrealDB. We will also explore CRUD statements and how to query data in SurrealDB.

What are the key features of a document model database?

Document model databases are designed to store data in a flexible, nested structure. They are often used for applications that require high performance, scalability, and flexibility. A

  1. Data Organization: Data is contained in self-describing documents, typically in JSON or a similar format. Relationships, can be done within the document itself (embedding) or references using record links to other documents.

  2. Schema Flexibility: Schemas are often flexible, allowing for documents of varying shapes in the same collection (or table-like structure).

For example, if you wanted to associate a person with an article they wrote, you could do this by assigning the person’s ID to the author field of the article document. This binds the person and article together, allowing you to query the article by the person’s ID.

Concepts mapping

When thinking in a document model database, you will often find that the concepts are similar to those in SurrealDB. Below is a mapping of the most common concepts between a document model database and SurrealDB.

Document ModelSurrealDB

database

database

collection

table

document

record

field

field

index

index

Objectid

record id

transactions

transactions

reference and embedding

record links, embedding and graph relations

Benefits of using a document model database

  1. Flexibility: You don’t need to define rigid schemas in advance. Changes to data structure are often just changes in the JSON object itself.

  2. Natural Data Representation: Since you’re working with JSON-like objects, document databases align well with modern programming languages that manipulate data as objects or dictionaries.

  3. Simplicity of Application Code: Because you can embed everything related to an entity in a single document, you often have fewer JOINs (or complex queries) and simpler code for retrieving complete objects.

  4. Easier Horizontal Scaling: Many document databases are built for horizontal partitioning (sharding), making them easier to scale for large workloads.

Creating and Managing Documents in SurrealDB

In SurrealDB, you can create a database and then store collections of documents (often referred to as “tables”) without strict schema definitions. Let’s walk through an example.

This is conceptually similar to creating a table in a relational database, but in SurrealDB you don’t necessarily need to define all columns upfront. Instead, you can just insert JSON-like objects.

Adding a Document

CREATE users CONTENT { name: "Alice Smith", email: "alice@example.com", age: 29, addresses: [ { type: "home", address_line: "123 Maple St", city: "Springfield", country: "USA" }, { type: "work", address_line: "456 Oak Ave", city: "Metropolis", country: "USA" } ] };

Here, we’ve created a user document with nested objects (addresses) in the same record. Notice how flexible this is: we can add as many nested objects or properties as we want, without having to modify any schema.

Retrieving Documents

SELECT * FROM users;

The above query returns all documents in the users table, much like a traditional SQL SELECT statement. Because SurrealDB is multi-model, the returned data might look like:

[ { "id": "users:xyz123", "name": "Alice Smith", "email": "alice@example.com", "age": 29, "addresses": [ { "type": "home", "address_line": "123 Maple St", "city": "Springfield", "country": "USA" }, { "type": "work", "address_line": "456 Oak Ave", "city": "Metropolis", "country": "USA" } ] } ]

SurrealDB automatically generates a unique id for the document. You can also specify your own custom IDs if you prefer more human-readable or domain-specific identifiers.

Using MongoDB Syntax as a reference

As a multi-model database, SurrealDB offers a lot of flexibility. Our SQL-like query language SurrealQL is a good example of this, where we often have more than one way to achieve the same result, depending on developer preference. In this mapping guide, we will focus on the syntax that most closely resembles the MongoDB query language (MQL).

Syntax mapping

Let’s get you up to speed with SurrealQL syntax with some CRUD examples.

Create

As MongoDB is schemaless, only the SurrealQL schemaless approach is shown below. For a schemafull option see the DEFINE TABLE page.

For more SurrealQL examples, see the CREATE and INSERT pages.

MQLSurrealQL

db.createCollection(“person”)

CREATE person

db.person.insertMany([{ name: “John” }, { name: “Jane” }])

INSERT INTO person [ {name: “John”}, {name: “Jane”} ]

db.person.createIndex({ name: 1 })

DEFINE INDEX idx_name ON TABLE person COLUMNS name

Read

For more SurrealQL examples, see the SELECT, LIVE SELECT and RETURN pages.

MQLSurrealQL

db.person.find()

SELECT * FROM person

db.person.find({}, { _id: 0, name: 1 })

SELECT name FROM person

db.person.find({ name: “Jane” }, { _id: 0, name: 1 })

SELECT name FROM person WHERE name = “Jane”

db.person.find({ name: “Jane” }, { _id: 0, name: 1 }).explain()

SELECT name FROM person WHERE name = “Jane” EXPLAIN

db.person.aggregate([{ $count: “personCount” }])

SELECT count() AS person_count FROM person GROUP ALL

db.person.aggregate([{ $group: { _id: “$name” } }])

SELECT array::distinct(name) FROM person GROUP ALL

db.person.find().limit(10)

SELECT * FROM person LIMIT 10

db.review.aggregate([{ “$lookup”: { “from”: “person”, “localField”: “person”, “foreignField”: “_id”, “as”: “person_detail” } }])

SELECT *, person.name as reviewer FROM review

Update

For more SurrealQL examples, see the UPDATE page.

MQLSurrealQL

db.person.updateMany({ name: “Jane” }, { $set: { last_name: “Doe” } })

UPDATE person SET last_name = “Doe” WHERE name = “Jane”

db.person.updateMany({ name: “Jane” }, { $unset: { last_name: 1 } })

UPDATE person UNSET last_name WHERE name = “Jane”

Delete

For more SurrealQL examples, see the DELETE and REMOVE pages.

MQLSurrealQL

db.person.deleteMany({ name: “Jane” })

DELETE person WHERE name = “Jane”

db.person.deleteMany({})

DELETE person

db.person.drop()

REMOVE TABLE person

Resources