Migration guide
The amount of changes in this new version is significant. If you were using a version older than v4, please also read this migration guide.
You should thoroughly test your application before deploying to production.
This document lists every known breaking change, not all of them may affect your application.
Common breaking changes
The changes below are effective on all of the API clients.
initIndex
Methods previously available at the initIndex
level are now available at the root
level of the API client.
The indexName
parameter is now required when calling those methods.
- C#
- Dart
- Go
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Scala
import { algoliasearch } from 'algoliasearch';
const client = algoliasearch('<YOUR_APP_ID>', '<YOUR_API_KEY>');
const searchResults = await client.search({
requests: [
{
indexName: '<YOUR_INDEX_NAME>',
query: '<YOUR_QUERY>',
attributesToRetrieve: ['firstname', 'lastname'],
hitsPerPage: 50,
},
],
});
from algoliasearch.search.client import SearchClient
client = SearchClient.create("YOUR_APP_ID", "YOUR_API_KEY")
searchResults = await client.search(search_method_params={"requests": [{"indexName": "nvim"}]})
$client = Algolia\AlgoliaSearch\Api\SearchClient::create(
'<YOUR_APP_ID>',
'<YOUR_API_KEY>'
);
$client->search([
'requests' => [
[
'indexName' => '<YOUR_INDEX_NAME>',
'query' => '<YOUR_QUERY>',
'attributesToRetrieve' => ['firstname', 'lastname'],
'hitsPerPage': 50,
],
],
]);
import com.algolia.model.search.*;
SearchClient client = new SearchClient(
"<YOUR_APP_ID>",
"<YOUR_API_KEY>"
);
client.search(
new SearchMethodParams()
.addRequests(
new SearchForHits()
.setIndexName("<YOUR_INDEX_NAME>")
.setQuery("<YOUR_QUERY>")
.addAttributesToRetrieve("firstname")
.addAttributesToRetrieve("lastname")
.setHitsPerPage(50)
)
);
A/B testing client
The A/B testing methods were previously available under the Analytics
client, we've decided to make a client out of it to split concerns.
The Abtesting
client now hosts all of the A/B testing
related methods.
- C#
- Dart
- Go
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Scala
Usage with the
algoliasearch
client
import { algoliasearch } from 'algoliasearch';
- const analyticsClient = algoliasearch('<YOUR_APP_ID>', '<YOUR_API_KEY>').initAnalytics();
+ const abtestingClient = algoliasearch('<YOUR_APP_ID>', '<YOUR_API_KEY>');
const abTest = await abtestingClient.getABTest({
id: 42,
});
Usage with the
client-abtesting
client
import { abtestingClient } from '@algolia/client-abtesting';
const client = abtestingClient('<YOUR_APP_ID>', '<YOUR_API_KEY>');
const abTest = await abtestingClient.getABTest({
id: 42,
});
Usage with the
algoliasearch
client
from algoliasearch.abtesting.client import AbtestingClient
- analytics_client = AnalyticsClient('<YOUR_APP_ID>', '<YOUR_API_KEY>');
+ abtesting_client = AbtestingClient('<YOUR_APP_ID>', '<YOUR_API_KEY>');
ab_test = await abtesting_client.get_ab_test(id=42);
- $client = AnalyticsClient::create('YOUR_APP_ID', 'YOUR_API_KEY');
+ $client = AbtestingClient::create('YOUR_APP_ID', 'YOUR_API_KEY');
$abTest = $client->getABTest(42);
import com.algolia.api.AbtestingClient;
import com.algolia.model.abtesting.*;
AbtestingClient client = new AbtestingClient("<YOUR_APP_ID>", "<YOUR_API_KEY>");
ABTest abTest = client.getABTest(42);
wait
The chainable wait
method that was available on a few methods has been replaced with an helper called waitForTask
.
You can now optionally configure how the wait logic behaves by passing the taskID
returned when calling the Algolia API.
Read more in our dedicated guide
- C#
- Dart
- Go
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Scala
import { algoliasearch } from 'algoliasearch';
const client = algoliasearch('<YOUR_APP_ID>', '<YOUR_API_KEY>');
const { taskID } = await client.saveObject({
indexName: '<YOUR_INDEX_NAME>',
body: {
title: 'My Algolia Object',
},
});
// Poll the task status with defaults values
await client.waitForTask({ indexName: '<YOUR_INDEX_NAME>', taskID });
from algoliasearch.search.client import SearchClient
client = SearchClient.create("YOUR_APP_ID", "YOUR_API_KEY")
save_resp = await client.save_object(index_name="nvim", body={"description": "blazing fast"})
# Poll the task status with defaults values
await client.wait_for_task(index_name="nvim", task_id=save_resp.task_id)
$client = SearchClient::create(
'<YOUR_APP_ID>',
'<YOUR_APP_ID>'
);
$response = $client->saveObject(
'<YOUR_INDEX_NAME>',
['title' => "My Algolia Object"],
);
// Poll the task status with defaults values
$client->waitForTask('<YOUR_INDEX_NAME>', $response['taskID']);
import com.algolia.model.search.*;
Map<String, Object> body = new HashMap<>();
body.put("title", "My Algolia Object");
SaveObjectResponse response = client.saveObject(
"<YOUR_INDEX_NAME>",
body
);
// Poll the task status with defaults values
client.waitForTask("<YOUR_INDEX_NAME>", response.getTaskID());
moveIndex
/copyIndex
The operationIndex
allows you to either copy
or move
a source
index to a destination
index within the same Algolia application.
You can also decide what scope
of the source
index should be copied, read more in our dedicated guide.
This method can be used as a replacement for the copyRules
, copySynonyms
, and copySettings
method when using the associated scope
.
- C#
- Dart
- Go
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Scala
import { algoliasearch } from 'algoliasearch';
const client = algoliasearch('<YOUR_APP_ID>', '<YOUR_API_KEY>');
const { taskID } = await client.operationIndex({
indexName: '<SOURCE_INDEX_NAME>',
operationIndexParams: {
// Enum for either `copy` or `move`
operation: 'copy', // 'move'
destination: '<DESTINATION_INDEX_NAME>',
},
});
// Poll the task status until it's done
await client.waitForTask({ indexName: '<SOURCE_INDEX_NAME>', taskID });
from algoliasearch.search.client import SearchClient
client = SearchClient.create("YOUR_APP_ID", "YOUR_API_KEY")
copy_resp = await client.operation_id(
index_name="<SOURCE_INDEX_NAME>",
operation_index_params={
# operation can either be `copy` or `move`
operation="copy",
destination="<DESTINATION_INDEX_NAME>",
},
)
# Poll the task status until it's done
await client.wait_for_task(index_name="<SOURCE_INDEX_NAME>", task_id=copy_resp.task_id)
$client = SearchClient::create(
'<YOUR_APP_ID>',
'<YOUR_APP_ID>'
);
$response = $client->operationIndex(
'<SOURCE_INDEX_NAME>',
[
// Enum for either `copy` or `move`
'operation' => 'copy', // 'move'
'destination' => '<DESTINATION_INDEX_NAME>'
]
);
// Poll the task status until it's done
$client->waitForTask('<SOURCE_INDEX_NAME>', $response['taskID']);
import com.algolia.model.search.*;
UpdatedAtResponse response = client.operationIndex(
"<SOURCE_INDEX_NAME>",
new OperationIndexParams()
.setOperation(OperationType.COPY) // or MOVE
.setDestination("<DESTINATION_INDEX_NAME>")
);
// Poll the task status until it's done
client.waitForTask("<SOURCE_INDEX_NAME>", response.getTaskID());
saveObjects
The saveObjects
method has been removed, you can leverage the already existing batch
method instead.
Read more in our dedicated guide or the API reference.
- C#
- Dart
- Go
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Scala
// The records retrieved by any of your data sources
const recordsFromDataSource = [
{ name: 'Tom Cruise' },
{ name: 'Scarlett Johansson' },
];
// Here we construct the request to be sent to Algolia with the `batch` method
const requests: BatchRequest[] = recordsFromDataSource.map((record) => {
return {
// `batch` allows you to do many Algolia operations, but here we want to index our record.
action: 'addObject',
body: record,
};
});
await client.batch({
indexName: '<YOUR_INDEX_NAME>',
batchWriteParams: {
requests,
},
});
# The records retrieved by any of your data sources
await client.batch({
index_name="<YOUR_INDEX_NAME>",
batch_write_params={
"requests":[
BatchRequest(action="addObject", body={ name: "Tom Cruise" })
BatchRequest(action="addObject", body={ name: "Scarlett Johansson" })
]
}
});
// The records retrieved by any of your data sources
$records = [
['name' => 'Tom Cruise'],
['name' => 'Scarlett Johansson']
];
// Here we construct the request to be sent to Algolia with the `batch` method
$requests = [];
foreach ($records as $record) {
$requests += [
'action' => 'addObject',
'body' => $record
];
}
$client->batch(
'<YOUR_INDEX_NAME>',
[ 'requests' => $requests ]
);
import com.algolia.model.search.*;
class Actor extends Hit {
public String name;
public Actor(String name) {
this.name = name;
}
}
// The records retrieved by any of your data sources
List<Actor> records = Arrays.asList(
new Actor("Tom Cruise"),
new Actor("Scarlett Johansson")
);
// Here we construct the request to be sent to Algolia with the `batch` method
List<BatchRequest> requests = new ArrayList<>();
for (Actor record : records) {
requests.add(new BatchRequest()
.setAction(Action.ADD_OBJECT)
// Accepts any serializable class.
.setBody(record)
);
}
client.batch("<YOUR_INDEX_NAME>", new BatchWriteParams().setRequests(batch));
browseObjects
/browseRules
/browseSynonyms
The browseObjects
/browseRules
/browseSynonyms
signature have changed to match the general usage of the API clients.
- C#
- Dart
- Go
- Java
- JavaScript
- Kotlin
- PHP
- Python
- Scala
// browse records
const records: Record<string, any> = [];
await client.browseObjects({
// all base `browse` options are forwarded to the `browse` method
indexName: '<YOUR_INDEX_NAME>',
// the aggregator to execute right after the API call has been resolved
aggregator: (response) => records.push(...response.hits),
});
console.log(records, records.length);
// browse rules
const rules: Record<string, any> = [];
await client.browseRules({
// all base `searchRules` options are forwarded to the `searchRules` method
indexName: '<YOUR_INDEX_NAME>',
// the aggregator to execute right after the API call has been resolved
aggregator: (response) => rules.push(...response.hits),
});
console.log(rules, rules.length);
// browse synonyms
const synonyms: Record<string, any> = [];
await client.browseSynonyms({
// all base `searchSynonyms` options are forwarded to the `searchSynonyms` method
indexName: '<YOUR_INDEX_NAME>',
// the aggregator to execute right after the API call has been resolved
aggregator: (response) => synonyms.push(...response.hits),
});
console.log(synonyms, synonyms.length);
# browse records
responses = []
await client.browse_objects(
# all base `browse` options are forwarded to the `browse` method
index_name="<YOUR_INDEX_NAME>"
aggregator=lambda _resp, responses.append(_resp)
)
print(responses)
# browse rules
rules = []
await client.browse_rules(
# all base `search_rules` options are forwarded to the `search_rules` method
index_name="<YOUR_INDEX_NAME>"
aggregator=lambda _resp, rules.append(_resp)
)
print(rules)
# browse synonyms
synonyms = []
await client.browse_synonyms(
# all base `search_synonyms` options are forwarded to the `search_synonyms` method
index_name="<YOUR_INDEX_NAME>"
aggregator=lambda _resp, synonyms.append(_resp)
)
print(synonyms)
// browse records
$results = $client->browseObjects($indexName);
$objects = [];
foreach ($results as $object) {
$objects[] = $object;
}
var_dump($objects);
// browse synonyms
$results = $client->browseSynonyms($indexName);
$synonyms = [];
foreach ($results as $synonym) {
$synonyms[] = $synonym;
}
var_dump($synonyms);
// browse rules
$results = $client->browseRules($indexName);
$rules = [];
foreach ($results as $rule) {
$rules[] = $rule;
}
var_dump($rules);
// browse records
Iterable<MyObject> objects = client.browseObjects(
"<YOUR_INDEX_NAME>",
// all base `browse` options are forwarded to the `browse` method
new BrowseParamsObject()
);
for (MyObject object : objects) {
System.out.println(object.myProperty);
}
// browse rules
Iterable<Rule> rules = client.browseRules(
"<YOUR_INDEX_NAME>",
// all base `searchRules` options are forwarded to the `searchRules` method (optional)
new SearchRulesParams()
);
for (Rule rule : rules) {
System.out.println(rule);
}
// browse synonyms
Iterable<SynonymHit> synonyms = client.browseRules(
"<YOUR_INDEX_NAME>",
// only search for specific types of synonyms. (optional)
null,
// all base `searchSynonyms` options are forwarded to the `searchSynonyms` method (optional)
new SearchSynonymsParams()
);
for (SynonymHit synonym : synonyms) {
System.out.println(synonym);
}
Client's specific breaking changes
You can find specific client breaking changes in their own section: