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 record
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
| require 'algolia'
client = Algolia::Search::Client.create('YourApplicationID', 'YourAdminAPIKey')
index = client.init_index('your_index_name')
|
1
2
3
4
5
6
7
8
9
10
11
| // For the default version
const algoliasearch = require('algoliasearch');
// For the default version
import algoliasearch from 'algoliasearch';
// For the search only version
import algoliasearch from 'algoliasearch/lite';
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
3
4
| import AlgoliaSearchClient
let client = SearchClient(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.saveObjects(objects).then(({ objectIDs }) => {
console.log(objectIDs);
});
|
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
8
9
10
11
12
13
14
15
16
| struct Contact: Encodable {
let objectID: ObjectID
let firstname: String
let lastname: String
}
let contacts: [Contact] = [
.init(objectID: "myID1", firstname: "Jimmie", lastname: "Barninger"),
.init(objectID: "myID2", firstname: "Warren", lastname: "Speach"),
]
try index.saveObjects(contacts) { result in
if case .success(let response) = result {
print("Response: \(response)")
}
}
|
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
| const objects = [{
firstname: 'Jimmie',
lastname: 'Barninger',
objectID: 'myID1'
}, {
firstname: 'Warren',
lastname: 'Speach',
objectID: 'myID2'
}];
index.saveObjects(objects).then(({ objectIDs }) => {
console.log(objectIDs);
});
|
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
8
9
10
11
12
13
14
15
16
17
18
| struct Contact: Encodable {
let objectID: ObjectID
let firstname: String
let lastname: String
}
let contacts: [Contact] = [
.init(objectID: "myID1", firstname: "Jimmie", lastname: "Barninger"),
.init(objectID: "myID2", firstname: "Warren", lastname: "Speach"),
]
let replacements = contacts.map {($0.objectID, $0) }
index.replaceObjects(replacements: replacements) { result in
if case .success(let response) = result {
print("Response: \(response)")
}
}
|
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
| const objects = [{
firstname: 'Jimmie',
objectID: 'myID1'
}, {
firstname: 'Warren',
objectID: 'myID2'
}];
index.partialUpdateObjects(objects).then(({ objectIDs }) => {
console.log(objectIDs);
});
|
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
| let updates: [(ObjectID, PartialUpdate)] = [
("myID1", .update(attribute: "firstname", value: "Jimmie")),
("myID2", .update(attribute: "firstname", value: "Warren"))
]
index.partialUpdateObjects(updates: updates) { result in
if case .success(let response) = result {
print("Response: \(response)")
}
}
|
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
| index.deleteObjects(['myID1', 'myID2']).then(({ objectIDs }) => {
console.log(objectIDs);
});
|
1
| index.delete_objects(['myID1', 'myID2'])
|
1
2
3
4
5
| index.deleteObjects(withIDs: ["myID1", "myID2"]) { result in
if case .success(let response) = result {
print("Response: \(response)")
}
}
|
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.