In order to copy records across Algolia applications, you can use the CopyIndex method. Usage examples of this method can be found in the API documentation.
When using this method with the .NET client, there are a few cases where the method doesn't make the exact copy of the source index. This document describes some tips to control the outcome of this method to avoid such issues.
Issue 1: Record attributes are not consistent across records, and the CopyIndex populates or ignores missing attributes
The .NET client applies serialization to records during the copy, which requires explicit type definition for the record structure.
If you need some flexibility in that process, you can use <JObject>, which allows you to serialize records dynamically.
// Copy `indexNameSrc` from app `SOURCE_APP_ID` to app `TARGET_APP_ID`
SearchClientsourceClient=newSearchClient("SOURCE_APP_ID","SOURCE_API_KEY");
SearchClienttargetClient=newSearchClient("TARGET_APP_ID","TARGET_API_KEY");
SearchIndexsourceIndex=sourceClient.initIndex("indexNameSrc");
SearchIndextargetIndex=targetClient.initIndex("indexNameDest");
// Serialize records as JObject type during copy
AccountClient.CopyIndex<JObject>(sourceIndex,targetIndex);
If you want to use a more explicit type definition while maintaining flexibility, you can add [JsonExtensionData] to populate the attributes dynamically, along with the attributes explicitly declared in the class.
public class Contact {
public string ObjectID { get; set; }
// Explicitly define "Address" attribute to use JsonProperty
[JsonProperty(PropertyName = "Address",NullValueHandling = NullValueHandling.Include)]
public string Address { get; set; }
// The rest of the attributes are dynamically populated by JsonExtensionData
[JsonExtensionData]
public IDictionary<string, object> CustomParameters { get; set; }
}
// Serialize records as Contact type during copy
AccountClient.CopyIndex<Contact>(sourceIndex,targetIndex);
Issue 2: Record attributes contain datetime values, and the CopyIndex method automatically converts its timezone or format
The default serializer of the .NET client parses date time values with the following settings. This can convert date time data format or timezone in record data.
DateParseHandling=DateParseHandling.DateTime
You can avoid such a conversion by creating a custom converter. The converter should look like the following.
public class DateParseHandlingConverter : JsonConverter
{
readonly DateParseHandling dateParseHandling;
public DateParseHandlingConverter(DateParseHandling dateParseHandling)
{
this.dateParseHandling = dateParseHandling;
}
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var old = reader.DateParseHandling;
try
{
reader.DateParseHandling = dateParseHandling;
existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
serializer.Populate(reader, existingValue);
return existingValue;
}
finally
{
reader.DateParseHandling = old;
}
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
and you can use the converter like the following example when defining the class.
[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)]
public class Contact
{
public string ObjectID { get; set; }
[JsonExtensionData]
public IDictionary<string, object> CustomParameters { get; set; }
}