In this tutorial, we’ll review how you can keep your data in sync with Algolia by updating incrementally
your records.
Putting an objectID in each records
In order to perform incremental updates after the initial indexing you will need declare a unique ID for each record.
This ID should map to a “key” that you store on your side (for example, a SKU
or PID
).
The unique ID needs to be stored in the objectID
attribute and can be leveraged to perform updates or deletions.
If you don’t specify a custom objectID
on creation, Algolia will generate it for you.
Initializing the client and index
1
2
3
4
5
6
7
8
9
10
11
12
| // composer autoload
require __DIR__ . '/vendor/autoload.php';
// if you are not using composer
// require_once 'path/to/algolia/folder/autoload.php';
$client = Algolia\AlgoliaSearch\SearchClient::create(
'YourApplicationID',
'YourAdminAPIKey'
);
$index = $client->initIndex('your_index_name');
|
1
2
3
4
5
6
| require 'rubygems'
require 'algoliasearch'
Algolia.init(application_id: 'YourApplicationID',
api_key: 'YourAdminAPIKey')
index = Algolia::Index.new('your_index_name')
|
1
2
3
4
5
6
7
8
9
10
11
| // const algoliasearch = require('algoliasearch');
// const algoliasearch = require('algoliasearch/reactnative');
// const algoliasearch = require('algoliasearch/lite');
// import * as algoliasearch from 'algoliasearch'; // When using TypeScript
// or just use algoliasearch if you are using a <script> tag
// if you are using AMD module loader, algoliasearch will not be defined in window,
// but in the AMD modules of the page
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey');
const index = client.initIndex('your_index_name');
|
1
2
3
4
| from algoliasearch.search_client import SearchClient
client = SearchClient.create('YourApplicationID', 'YourAdminAPIKey')
index = client.init_index('your_index_name')
|
1
2
| let client = Client(appID: "YourApplicationID", apiKey: "YourAdminAPIKey")
let index = client.index(withName: "your_index_name")
|
1
2
| Client client = new Client("YourApplicationID", "YourAdminAPIKey");
Index index = client.getIndex("your_index_name");
|
1
2
| SearchClient client = new SearchClient("YourApplicationID", "YourAdminAPIKey");
SearchIndex index = client.InitIndex("your_index_name");
|
1
2
3
4
| SearchClient client =
DefaultSearchClient.create("YourApplicationID", "YourAdminAPIKey");
SearchIndex<Contact> index = client.initIndex("your_index_name", Contact.class);
|
1
2
| client := search.NewClient("YourApplicationID", "YourAdminAPIKey")
index := client.InitIndex("your_index_name")
|
1
2
| // No initIndex
val client = new AlgoliaClient("YourApplicationID", "YourAdminAPIKey")
|
1
2
3
4
5
6
7
| val client = ClientSearch(
applicationID = ApplicationID("latency"),
apiKey = APIKey("YourAdminAPIKey")
)
val indexName = IndexName("your_index_name")
client.initIndex(indexName)
|
Add records
Objects can be added using the following method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $index->saveObjects(
[
[
'objectID' => 'myID1',
'firstname' => 'Jimmie',
'lastname' => 'Barninger'
],
[
'objectID' => 'myID2',
'firstname' => 'Warren',
'lastname' => 'Speach'
]
]
);
|
1
2
3
4
5
6
7
8
9
| res = index.save_objects([{
firstname: 'Jimmie',
lastname: 'Barninger',
objectID: 'myID1'
}, {
firstname: 'Warren',
lastname: 'Speach',
objectID: 'myID2'
}])
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| const objects = [{
objectID: 'myID1',
firstname: 'Jimmie',
lastname: 'Barninger'
}, {
objectID: 'myID2',
firstname: 'Warren',
lastname: 'Speach'
}];
index.addObjects(objects, (err, content) => {
console.log(content);
});
|
1
2
3
4
| res = index.save_objects([
{"objectID": "myID1", "firstname": "Jimmie", "lastname": "Barninger"},
{"objectID": "myID2", "firstname": "Warren", "lastname": "Speach"}
])
|
1
2
3
4
5
6
7
| let obj1 = ["objectID": "myID1", "firstname": "Jimmie", "lastname": "Barninger"]
let obj2 = ["objectID": "myID2", "firstname": "Warren", "lastname": "Speach"]
index.addObjects([obj1, obj2], completionHandler: { (content, error) -> Void in
if error == nil {
print("Object IDs: \(content!)")
}
})
|
1
2
3
4
5
6
7
8
9
10
11
12
| List<JSONObject> array = new ArrayList<JSONObject>();
array.add(
new JSONObject().put("objectID", "myID1")
.put("firstname", "Jimmie").put("lastname", "Barninger")
);
array.add(
new JSONObject().put("objectID", "myID2")
.put("firstname", "Warren").put("lastname", "Speach")
);
index.addObjectsAsync(new JSONArray(array), null);
|
1
2
3
4
5
6
7
8
9
10
| List<Contact> contacts = new List<Contact>
{
new Contact { ObjectID = "myID1", Firstname = "Jimmie", Lastname = "Barninger" },
new Contact { ObjectID = "myID2", Firstname = "Warren", Lastname = "Speach" }
};
index.SaveObjects(contacts);
// Asynchronous
await index.SaveObjectsAsync(contacts);
|
1
2
3
4
5
6
7
8
9
| List<Contact> contacts = Arrays.asList(
new Contact().setObjectID("myID1").setFirstName("Jimmie").setLastName("Barninger"),
new Contact().setObjectID("myID2").setFirstName("Warren").setLastName("Speach"));
// Sync version
index.saveObjects(contacts);
// Async version
index.saveObjectsAsync(contacts);
|
1
2
3
4
5
6
7
8
9
10
11
12
| type Contact struct {
ObjectID string `json:"objectID"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
}
contacts := []Contact{
{ObjectID: "myID1", Firstname: "Jimmie", Lastname: "Barninger"},
{ObjectID: "myID2", Firstname: "Ray", Lastname: "Charles"},
}
res, err := index.SaveObjects(contacts)
|
1
2
3
4
5
6
| client.execute {
index into "index1" objects Seq(
Contact("myID1", "Jimmie", "Barninger"),
Contact("myID2", "Warren", "Speach")
)
}
|
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
| // With JsonObject
val json = listOf(
json {
"objectID" to ObjectID("myID1")
"firstname" to "Jimmie"
"lastname" to "Barninger"
},
json {
"objectID" to ObjectID("myID2")
"firstname" to "Warren"
"lastname" to "Speach"
}
)
index.saveObjects(json)
// With serializable class
@Serializable
data class Contact(
val firstname: String,
val lastname: String,
override val objectID: ObjectID
) : Indexable
val contacts = listOf(
Contact("Jimmie", "Barninger", ObjectID("myID")),
Contact("Jimmie", "Barninger", ObjectID("myID"))
)
index.saveObjects(Contact.serializer(), contacts)
|
Notice that an objectID
is specified for each record.
Additional methods for importing data
There are many ways to push data to Algolia, the full extent of which
bare covered in our importing with the API tutorial.
Updating records
There are two ways to update a record in Algolia.
By replacing the old record
To replace the content of an object that is already indexed in Algolia, you will need to save the new version of the object:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $res = $index->saveObjects(
[
[
'objectID' => 'myID1',
'firstname' => 'Jimmie',
'lastname' => 'Barninger'
],
[
'objectID' => 'myID2',
'firstname' => 'Warren',
'lastname' => 'Speach'
]
]
);
|
1
2
3
4
5
6
7
8
9
| res = index.save_objects([{
firstname: 'Jimmie',
lastname: 'Barninger',
objectID: 'myID1'
}, {
firstname: 'Warren',
lastname: 'Speach',
objectID: 'myID2'
}])
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| const objects = [{
firstname: 'Jimmie',
lastname: 'Barninger',
objectID: 'myID1'
}, {
firstname: 'Warren',
lastname: 'Speach',
objectID: 'myID2'
}];
index.saveObjects(objects, (err, content) => {
if (err) throw err;
console.log(content);
});
|
1
2
3
4
| res = index.save_objects([
{'firstname': 'Jimmie', 'lastname': 'Barninger', 'objectID': 'myID1'},
{'firstname': 'Warren', 'lastname': 'Speach', 'objectID': 'myID2'}
])
|
1
2
3
4
5
6
7
| let obj1 = ["firstname": "Jimmie", "lastname": "Barninger", "objectID": "myID1"]
let obj2 = ["firstname": "Warren", "lastname": "Speach", "objectID": "myID2"]
index.saveObjects([obj1, obj2], completionHandler: { (content, error) -> Void in
if error == nil {
print("Object IDs: \(content!)")
}
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| List<JSONObject> array = new ArrayList<JSONObject>();
array.add(
new JSONObject()
.put("firstname", "Jimmie")
.put("lastname", "Barninger")
.put("objectID", "myID")
);
array.add(
new JSONObject()
.put("firstname", "Warren")
.put("lastname", "Speach")
.put("objectID", "myID2")
);
index.saveObjectsAsync(new JSONArray(array), null);
|
1
2
3
4
5
6
7
8
9
10
| List<Contact> contacts = new List<Contact>
{
new Contact { ObjectID = "myID1", Firstname = "Jimmie", Lastname = "Barninger" },
new Contact { ObjectID = "myID2", Firstname = "Warren", Lastname = "Speach" }
};
index.SaveObjects(contacts);
// Asynchronous
await index.SaveObjectsAsync(contacts);
|
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
| // Sync version
index.saveObjects(Arrays.asList(
new Contact()
.setFirstName("Jimmie")
.setLastName("Barninger")
.setObjectID("myID"),
new Contact()
.setFirstName("Warren")
.setLastName("Speach")
.setObjectID("myID2")
));
// Async version
index.saveObjectsAsync(Arrays.asList(
new Contact()
.setFirstName("Jimmie")
.setLastName("Barninger")
.setObjectID("myID"),
new Contact()
.setFirstName("Warren")
.setLastName("Speach")
.setObjectID("myID2")
));
|
1
2
3
4
5
6
7
8
9
10
11
12
| type Contact struct {
ObjectID string `json:"objectID"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
}
contacts := []Contact{
{ObjectID: "myID1", Firstname: "Jimmie", Lastname: "Barninger"},
{ObjectID: "myID2", Firstname: "Ray", Lastname: "Charles"},
}
res, err := index.SaveObjects(contacts)
|
1
2
3
4
5
6
| client.execute {
index into "index1" objects Seq(
Contact("myID1", "Jimmie", "Barninger"),
Contact("myID2", "Warren", "Speach")
)
}
|
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
| // With JsonObject
val json = listOf(
ObjectID("myID1") to json {
"firstname" to "Jimmie"
"lastname" to "Barninger"
},
ObjectID("myID1") to json {
"firstname" to "Warren"
"lastname" to "Speach"
}
)
index.replaceObjects(json)
// With serializable class
@Serializable
data class Contact(
val firstname: String,
val lastname: String,
override val objectID: ObjectID
) : Indexable
val contacts = listOf(
Contact("Jimmie", "Barninger", ObjectID("myID")),
Contact("Jimmie", "Barninger", ObjectID("myID"))
)
index.replaceObjects(Contact.serializer(), contacts)
|
Notice that the objectID in the new version of the object matches the initial objectID.
By updating only a subset of the record
In some cases you may only want to update a subset of the attributes of a record. To accomplish this, you will need to use
the Partial update objects method:
1
2
3
4
5
6
7
8
9
10
11
12
| $index->partialUpdateObjects(
[
[
'objectID' => 'myID1',
'firstname' => 'Jimmie'
],
[
'objectID' => 'myID2',
'firstname' => 'Warren'
]
]
);
|
1
2
3
4
5
6
7
| index.partial_update_objects([{
firstname: 'Jimmie',
objectID: 'myID'
}, {
firstname: 'Warren',
objectID: 'myID2'
}])
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| const objects = [{
firstname: 'Jimmie',
objectID: 'myID1'
}, {
firstname: 'Warren',
objectID: 'myID2'
}];
index.partialUpdateObjects(objects, (err, content) => {
if (err) throw err;
console.log(content);
});
|
1
2
3
4
| index.partial_update_objects([
{'objectID': 'myID1', 'firstname': 'Jimmie'},
{'objectID': 'myID2', 'firstname': 'Warren'}
])
|
1
2
3
4
5
6
7
8
9
10
11
| let obj1 = ["firstname": "Jimmie", "objectID": "myID1"]
let obj2 = ["firstname": "Warren", "objectID": "myID2"]
index.partialUpdateObjects(
[obj1, obj2],
completionHandler: { (content, error) -> Void in
if error == nil {
print("Object IDs: \(content!)")
}
}
)
|
1
2
3
4
5
6
7
8
9
10
| List<JSONObject> array = new ArrayList<JSONObject>();
array.add(
new JSONObject().put("firstname", "Jimmie").put("objectID", "myID")
);
array.add(
new JSONObject().put("firstname", "Warren").put("objectID", "myID2")
);
index.partialUpdateObjectsAsync(new JSONArray(array), null);
|
1
2
3
4
5
6
7
8
9
10
| List<Contact> contacts = new List<Contact>
{
new Contact { ObjectID = "myID1", Firstname = "Jimmie" },
new Contact { ObjectID = "myID2", Firstname = "Warren" }
};
index.PartialUpdateObjects(contacts);
// Asynchronous
await index.PartialUpdateObjectsAsync(contacts);
|
1
2
3
4
5
6
7
8
9
10
| List<Contact> contacts = Arrays.asList(
new Contact().setCity("San Francisco").setObjectID("MyID"),
new Contact().setCity("Paris").setObjectID("MyID2")
);
// Sync version
index.partialUpdateObjects(contacts);
// Async version
index.partialUpdateObjectsAsync(contacts);
|
1
2
3
4
5
6
| objects := []map[string]string{
{"objectID": "myID1", "lastname": "Barninger"},
{"objectID": "myID2", "firstname": "Ray"},
}
res, err := index.PartialUpdateObjects(objects)
|
1
2
3
4
5
6
| client.execute {
partialUpdate from "index" objects Seq(
Contact("myID", "Jimmie", "Barninger"),
Contact("myID", "Speach")
)
}
|
1
2
3
4
5
6
7
| val firstname = Attribute("firstname")
val partials = listOf(
ObjectID("myID1") to Partial.Update(firstname, "Jimmie"),
ObjectID("myID2") to Partial.Update(firstname, "Warren")
)
index.partialUpdateObjects(partials)
|
Notice that the objectID in the new version of the object matches the initial objectID.
Deleting records
To delete an object, you will need to delete the object using its objectID:
1
| $index->deleteObjects(["myID1", "myID2"]);
|
1
| index.delete_objects(['myID1', 'myID2'])
|
1
2
3
4
5
| index.deleteObjects(['myID1', 'myID2'], (err, content) => {
if (err) throw err;
console.log(content);
});
|
1
| index.delete_objects(['myID1', 'myID2'])
|
1
| index.deleteObjects(withIDs: ["myID1", "myID2"])
|
1
| index.deleteObjectsAsync(Arrays.asList("myID1", "myID2"), null);
|
1
2
3
4
5
6
| List<string> ids = new List<string> { "myID1", "myID2" };
index.DeleteObjects(ids);
// Asynchronous
await index.DeleteObjectsAsync(ids);
|
1
2
3
4
5
| // Sync version
index.deleteObjects(Arrays.asList("myID1", "myID2"));
// Async version
index.deleteObjectsAsync(Arrays.asList("myID1", "myID2"));
|
1
2
3
| res, err := index.DeleteObjects(
[]string{"myID1", "myID2"},
)
|
1
2
3
| client.execute {
delete from "test1" objectIds Seq("1", "2")
}
|
1
2
3
| val objectIDS = listOf(ObjectID("myID1"), ObjectID("myID2"))
index.deleteObjects(objectIDS)
|
Notice that the objectID in the new version of the object matches the initial objectID.
Delete by query
In some cases you may need to delete all the records that match a certain search query.
To accomplish this, you will need to leverage the Delete by method.
Don’t forget that any attributes you’re querying to delete by will need to be included in your searchable attributes settings.