Rob

Couchbase Mobile: The Power of NoSQL on the Edge

In a perfect world we’d always have a fast, reliable network connection on our mobile devices. Unfortunately, whether you’re driving through the middle of nowhere, surrounded by thousands of other people using their phones, or even in an area that should be a prime location for data, it’s inevitable that you’ll encounter connectivity issues. Luckily, problems like this can be mitigated by storing data locally.
If you’re unfamiliar with the mobile and IoT (or as the kids are calling it these days, the edge) database landscape you’ll likely head straight to your favorite search engine to investigate the options.
Spoiler alert... there’s a lot.
And while there are a plethora of options for you to choose from, unfortunately, like so many other topics in tech, there’s no silver bullet that’s going to cure all your “edge ailments”. There are, however, solutions that stand out among the rest. One of those is Couchbase.

Couchbase on the Edge

Couchbase, Inc., at its core, is a company that offers a distributed NoSQL database that can be hosted locally, on premises, or within all the major cloud providers. OK, great, but what does that have to do with mobile and IoT?
Couchbase Mobile extends Couchbase to that glorious edge by providing the ability to securely manage and synchronize data from any cloud/server to every mobile device with three major pieces:
  1. Couchbase Lite, an embedded, NoSQL JSON Document Style database for your mobile apps
  2. Sync Gateway, an internet-facing synchronization mechanism that securely syncs data between mobile clients and server, and
  3. Couchbase Server, a highly scalable, distributed NoSQL database platform.

Couchbase Lite

As previously mentioned, Couchbase Lite is an embedded lightweight, NoSQL document-oriented, sync-able database engine. While relational databases are made up a collection of tables filled with rows of information, document databases store data in JSON blobs like the following:
{
  "name": "Rob",
  "age": 34,
  "type": "person"
}
  • Fun fact: Couchbase Lite actually uses a much more efficient binary encoding solution known as Fleece.
Storing information in documents provides flexibility and scalability advantages that are particularly helpful when used within mobile and IoT applications.
That's the gist of Couchbase Lite but you're probably wondering, where's the beef? What is Couchbase Lite supported on, and how can you use it? Couchbase Lite is supported on iOS, Android, Xamarin, IoT apps, and provides a variety of easy to implement features that make creating truly resilient apps a piece of cake. So let's dive in!

Basic CRUD Operations

Couchbase Lite supports all the CRUD operations you'd expect from a database solution. Below is a simple example of creating and saving a MutableDocument.
Swift (iOS)
let doc = MutableDocument()
    .setString("person", forKey: "type")
    .setString("Rob", forKey: "name")
    .setInt(34, forKey: "age")
try database.saveDocument(doc)
Java (Android)
MutableDocument doc = new MutableDocument();
newTask.setString("type", "person");
newTask.setString("name", "Rob");
newTask.setInt("age", 34);
try {
    database.save(doc);
} catch (CouchbaseLiteException e) {
    Log.e(TAG, e.toString());
}
C# (Xamarin)
using (var doc = new MutableDocument("person::1")) 
{
    doc.SetString("type", "person");
    doc.SetString("name", "Rob");
    doc.SetInt("age", 34);

    db.Save(doc);
}
  • Tip: It's even easier to perform CRUD operations with Xamarin based apps using an extension Nuget package called Couchbase.Lite.Mapping!

Querying

Couchbase Lite queries have changed significantly. Instead of the map/reduce views used in 1.x, they’re now based on expressions, of the form "return ____ from documents where ____, ordered by ____", with semantics based on Couchbase’s N1QL query language.
There are several parts to specifying a query:
  • SELECT - Specifies the projection, which is the part of the document that is to be returned.
  • FROM - Specifies the database to query the documents from.
  • JOIN - Specifies the matching criteria in which to join multiple documents.
  • WHERE - Specifies the query criteria that the result must satisfy.
  • GROUP BY - Specifies the query criteria to group rows by.
  • ORDER BY - Specifies the query criteria to sort the rows in the result
Below is a simple query used to retrieve all "person" documents from a Couchbase Lite database.
Swift (iOS)
let query = QueryBuilder
    .select(SelectResult.all())
    .from(DataSource.database(database))
    .where(Expression.property("type").equalTo(Expression.string("person"))))
Java (Android)
Query query = QueryBuilder
    .select(SelectResult.all())
    .from(DataSource.database(database))
    .where(Expression.property("type").equalTo(Expression.string("person"))));
C# (Xamarin)
    var query = QueryBuilder.Select(SelectResult.All())
    .From(DataSource.Database(db))
    .Where(Expression.Property("type").EqualTo(Expression.String("person"))));
  • Tip: It's also even easier to perform query operations with Xamarin based apps using an extension Nuget package called Couchbase.Lite.Mapping!
The next step in querying on Couchbase Mobile revolves around live queries. Live queries stays active and monitor the database for changes. A live query is a great way to build reactive user interfaces, especially table/list views, that keep themselves up to date. 
By simply adding a listener to a query you'll be able to receive real-time updates to your Couchbase Lite database.
Swift (iOS)
let token = query.addChangeListener { (change) in
for result in change.results! {
    print(result.keys)
}
Java (Android)
ListenerToken token = query.addChangeListener(change -> {
    for (Result result: change.getResults()) {
        Log.d(TAG, "results: " + result.getKeys());
    }
});
C# (Xamarin)
var token = query.AddChangeListener((sender, args) =>
{
    var allResult = args.Results.AllResults();
    foreach (var result in allResult) {
        Console.WriteLine(result.Keys);
    }
});

Full-text search

Full Text Search (FTS) lets you create, manage, and query specially purposed indexes, defined on documents within a Couchbase Lite database. FTS provides extensive capabilities for natural-language querying.
Creating an FTS index:
do {
    let index = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property("name")).ignoreAccents(false)
    try database.createIndex(index, withName: "nameFTSIndex")
} catch let error {
    print(error.localizedDescription)
}
database.createIndex(
    "nameFTSIndex",
    IndexBuilder.fullTextIndex(FullTextIndexItem.property("name")).ignoreAccents(false));
var index = IndexBuilder.FullTextIndex(FullTextIndexItem.Property("name")).IgnoreAccents(false);
db.CreateIndex("nameFTSIndex", index);
Creating an FTS query:
Once an index is created, an FTS query on the property that is being indexed can be constructed and executed. The FTS criteria is defined as a FullTextExpression. The left-hand side is the full-text index to use and the right-hand side is the pattern to match.
Swift (iOS)
let whereClause = FullTextExpression.index("nameFTSIndex").match("'buy'")
let query = QueryBuilder
    .select(SelectResult.expression(Meta.id))
    .from(DataSource.database(database))
    .where(whereClause)

do {
    for result in try query.execute() {
        print("document id \(result.string(at: 0)!)")
    }
} catch let error {
    print(error.localizedDescription)
}
Java (Android)
Expression whereClause = FullTextExpression.index("nameFTSIndex").match("buy");
Query ftsQuery = QueryBuilder.select(SelectResult.expression(Meta.id))
    .from(DataSource.database(database))
    .where(whereClause);
ResultSet ftsQueryResult = ftsQuery.execute();
for (Result result : ftsQueryResult) {
    Log.i(
        TAG,
        String.format("document properties %s", result.getString(0)));
}
C# (Xamarin)
var whereClause = FullTextExpression.Index("nameFTSIndex").Match("'buy'");
using (var query = QueryBuilder.Select(SelectResult.Expression(Meta.ID))
    .From(DataSource.Database(db))
    .Where(whereClause)) {
    foreach (var result in query.Execute()) {
        Console.WriteLine($"Document id {result.GetString(0)}");
    }
}

Predictive querying

Predictive Querying enables Couchbase Lite queries to use machine learning, by providing query functions that can process document data (properties or blobs) via trained machine learning models.
Consider an image classifier model that takes a picture as input and outputs a label and probability.
Couchbase Lite predictive queries allows you to integrate the ML model, and run a prediction query. For more information and samples check out the latest documentation for iOS, Android, and Xamarin.

Peer-to-peer Replication

Peer-to-peer sync allows devices running Couchbase Lite to directly synchronize data with each other. As part of this, Couchbase Lite is responsible for storing the data and keeping track of the data exchange, but isn’t responsible for the data transfer itself.
Note: Sending and receiving data must be handled by the platform APIs or a third party framework.

Sync Gateway

Sync Gateway is a horizontally scalable web server that securely manages the access control and synchronization of data between Couchbase Lite and Couchbase Server.
For most mobile developers, it comes as no surprise that creating synchronization solutions can be a pain. After all, there's a lot that goes into creating something that can handle things like:
  • Conflict resolution capabilities for documents that can be updated or deleted by multiple users at the same time.
  • A flexible configuration to adapt to changing needs
  • Regulating/controlling access to data through authentication and authorization.
  • Limit the amount of unnecessary data from being replicated between embedded database instances.
Luckily, Sync Gateway covers all of those and more!

Conflict Resolution

Since Couchbase Lite 2.0 (released in 2018), conflicts are automatically resolved. Seriously. AUTOMATICALLY.

Configuration

The configuration file determines the runtime behavior, including server configuration and the database or a set of databases, that Sync Gateway can interact with.
Configuration files can be as simple or complex as you need them to be in. Below is simple example of a Sync Gateway configuration file.
{
  "logging": {
    "console": {
     "log_level": "debug",
     "log_keys": ["*"],
     "color_enabled": false
   }
  },
  "databases": {
    "couchdraw": {
      "server": "http://localhost:8091",
      "bucket": "couchdraw",
      "username": "couchdraw_user",
      "password": "password",
      "num_index_replicas": 0,
      "enable_shared_bucket_access": true,
      "import_docs": "continuous",
      "users": { "GUEST": { "disabled": false, "admin_channels": ["*"] } },
      "allow_conflicts": false,
      "revs_limit": 20
    }
  }
}
To learn more about Sync Gateway configuration files take a look at the full documentation here!

Access Control

Sync Gateway supports several avenues of authentication.
  • Basic Authentication: Provide a username and password to authenticate users.
  • Auth Providers: Sync Gateway provides a turn-key solution to authenticate with Facebook or Google. For other providers we recommend to use Custom Authentication or OpenID Connect.
  • Custom Authentication: Use an App Server to handle the authentication yourself and create user sessions on the Sync Gateway Admin REST API.
  • OpenID Connect Authentication: Use OpenID Connect providers (Google+, Paypal, etc.) to authenticate users. Static providers: Sync Gateway currently supports authentication endpoints for Facebook, Google+ and OpenID Connect provider

Data routing

Sync Gateway uses channels to make it easy to share a database between a large number of users and control access to the database. Channels are the intermediaries between documents and users. Every document in the database belongs to a set of channels, and every user is allowed to access a set of channels. You can use channels to:
  • Partition the data set.
  • Authorize users to access documents.
  • Minimize the amount of data synced down to devices

Couchbase Server

Couchbase Server is an open source, distributed, NoSQL document-oriented engagement database. It specializes in providing low-latency data management for interactive web, mobile, and IoT applications. 
Couchbase Lite through Sync Gateway, though not a strict requirement, seamlessly integrates with Couchbase Server to provide a complete end-to-end solution on the edge.

Learn More

If you'd like to know more about how use Couchbase Mobile within your mobile or IoT app consider checking out recent tutorials for iOS, Android, and Xamarin put out by the Couchbase team.
Also, if you're interesting in learning more about the latest and greatest features of Couchbase Mobile check out the newest episode of Gone Mobile!

Tags

Comments

More by Rob

Topics of interest