Scott Smith

Blog Tutorials Projects Speaking RSS

Algolia Real Time Search With Parse

One key feature of Parse is for applications to use Parse Core as their data store. In a few simple steps, this tutorial will teach you how to import your existing data, index new data as it is added to Parse, and remove indexed data when it is removed from Parse.

The Algolia Parse Module simplifies the integration of your Parse based applications with Algolia’s real time search service. The module makes it easy for you to use Algolia’s search capabilities in a manner that will be familiar to those already using the Algolia Node.js client APIs.

Prerequisites

Familiar with Parse

This tutorial assumes you are familiar with Parse, how it works, and how to build Cloud Code applications. If you would like to learn more before continuing with this tutorial, I suggest reading the following documentation and tutorials:

  1. Getting started with Cloud Code
  2. Parse quickstart web project
  3. Parse quickstart Cloud Code project on Mac/Linux
  4. Parse quickstart Cloud Code project on Windows

Add Agolia Real Time Search to the Project

In order to integrate Aloglia within your Parse application, you will need to add the Algolia Node.js client. Copy algoliasearch.parse.js to cloud/algoliasearch.parse.js within your Parse Cloud Code directory.

Import Existing Data

In many cases, you may already have data within your Parse application. In order to integrate with Algolia, you will want to index that data. We will use contact information being stored within Parse as our example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('YourApplicationID', 'YourAPIKey');
var index = client.initIndex('contacts');

function indexData() {
  var objectsToIndex = [];

  //Create a new query for Contacts
  var query = new Parse.Query('Contact');

  // Find all items
  query.find({
    success: function(contacts) {
      // prepare objects to index from contacts
      objectsToIndex = contacts.map(function(contact) {
        // convert to regular key/value JavaScript object
        contact = contact.toJSON();

        // Specify Algolia's objectID with the Parse.Object unique ID
        contact.objectID = contact.objectId;

        return contact;
      });

      // Add or update new objects
      index.saveObjects(objectsToIndex, function(err, content) {
        if (err) {
          throw err;
        }

        console.log('Parse<>Algolia import done');
      });
    },
    error: function(err) {
      throw err;
    }
  });
}

You can now use this function within your own Parse Cloud Code functions in order to index your existing data.

Be sure to change ‘YourApplicationID’ and ‘YourAPIKey’ to your account values here. Because we are making calls that require more than read access, you will need to create a new key or use an existing one that can Add Records, Delete Records, and Delete Index (for reindexing example). If you create a new key, you will need to make sure it can Add Records and Delete Records.

Reindex Data

Sometimes, you may have the need to completely reindex your data. This means removing data from the index that may not longer exist, adding new data, and updating existing data. The following code can be used within your own Parse Cloud Code functions to perform a reindexing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
var tempIndexName = 'contacts_temp';
var mainIndexName = 'contacts';
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('YourApplicationID', 'YourAPIKey');
var tempIndex = client.initIndex(tempIndexName);

var reindexData = function() {
  var objectsToIndex = [];

  // Create a temp index
  var tempIndex = client.initIndex(tempIndexName);

  // Create a new query for Contacts
  var query = new Parse.Query('Contact');

  // Find all items
  query.find({
    success: function(contacts) {
      // prepare objects to index from contacts
      objectsToIndex = contacts.map(function(contact) {
        // convert to regular key/value JavaScript object
        contact = contact.toJSON();

        // Specify Algolia's objectID with the Parse.Object unique ID
        contact.objectID = contact.objectId;

        return contact;
      });

      // Add new objects to temp index
      tempIndex.saveObjects(objectsToIndex, function(err, content) {
        if (err) {
          throw err;
        }

        // Overwrite main index with temp index
        client.moveIndex(tempIndexName, mainIndexName, function(err, content) {
          if (err) {
            throw err;
          }

          console.log('Parse<>Algolia reimport done');
        });
      });
    },
    error: function(err) {
      throw err;
    }
  });
};

Add or Update Data

Now, we need to handle the case where data is being added or updated. We can easily setup our code to automatically add or update data to our search index by using the afterSave Parse function. This will allow us to define code that will be called after data is stored in Parse.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('YourApplicationID', 'YourAPIKey');
var index = client.initIndex('contacts');

Parse.Cloud.afterSave('Contact', function(request) {
  // Convert Parse.Object to JSON
  var objectToSave = request.object.toJSON();

  // Specify Algolia's objectID with the Parse.Object unique ID
  objectToSave.objectID = objectToSave.objectId;

  // Add or update object
  index.saveObject(objectToSave, function(err, content) {
    if (err) {
      throw err;
    }

    console.log('Parse<>Algolia object saved');
  });
});

Now, whenever contact data is saved in Parse, it will automatically be indexed with Algolia.

Delete Data

Next, we need to handle the case where data is deleted from your Parse application. In order to do this, we can use the afterDelete Parse function. This will allow us to define code that will be called after data is removed from Parse.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var algoliasearch = require('cloud/algoliasearch.parse.js');
var client = algoliasearch('YourApplicationID', 'YourAPIKey');
var index = client.initIndex('contacts');

Parse.Cloud.afterDelete('Contact', function(request) {
  // Get Algolia objectID
  var objectID = request.object.id;

  // Remove the object from Algolia
  index.deleteObject(objectID, function(err, content) {
    if (err) {
      throw err;
    }

    console.log('Parse<>Algolia object deleted');
  });
});

Now, whenever contact data is removed from Parse, it will automatically get removed from Algolia.

Next Steps

  1. Read the Node.js documentation
  2. Dive into the Node.js command reference
  3. Explore the Node.js API client source code