Skip to content

Integrating and Updating Entities

This page offers examples on integrating and updating products and content entities in Relewise.

Relewise has a .NET SDK which, among other things, will make implementing tracking very easy.

It is available via NuGet.

Read more about how to authenticate against our API here.

Integrating and Updating Products with .NET

To get products into Relewise, follow the template laid out below. Be aware of different data types and when to use the correct one.

Add whatever fields are necessary for your integration to be useful for your search and/or recommendation requirements.

If you are unsure of what entity-actions to take, refer to our list of entity-actions.


To update or import the details of a single product you can make a TrackProductUpdateRequest.

The following request uses ProductUpdateUpdateKind::ReplaceProvidedProperties which creates a new product if the product hasn't been tracked before and else updates the properties set in the request for that product.

csharp
async Task Main()
{
	// Copy dataset id + API key + server URL from 
	// my.relewise.com > Administration -> API Keys
	var tracker = new Tracker(new Guid("00000000-0000-0000-0000-000000000001"),
	 "your api key", "the server URL for the dataset");		
	// This is the recommended "Push" method, for importing product data into Relewise.
	await FullProductUpdates(tracker); 
	// Note all methods have a synchronous as well as an asynchronous counterpart, 
	// e.g. Tracker.Track / Tracker.TrackAsync
}

private Task FullProductUpdates(ITracker tracker)
{
	// Create a timestamp to distinguish active and inactive entities
	// Read more at
	// https://docs.relewise.com/docs/developer/bestpractices/product-integration.html
	double importTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

	// Language can be any string, and doesn't have to be a valid iso-standard.
	Language english = new Language("en"); 
	Currency dkk = new Currency("DKK");

	List<Trackable> productUpdates = new List<Trackable>();

	// Foreach product that needs to be imported, do the following:
	{
		// The Id should be the primary id of the product
		Product product = new Product("Product-SKU-01"); 
		// We only set the English translation in this example 
		// but more can be set by parsing more MultilingualValue 
		// to the Multilingual::create method.
		product.DisplayName = new Multilingual(new Multilingual.Value(
			english, "The english display name")); 
		
		product.Brand = new Brand("brandId")
		{
			// Displayname can be left out, but Id is required
			DisplayName = "Brand display name" 
		};

		product.CategoryPaths.Add(new CategoryPath(
			new CategoryNameAndId("74", new Multilingual(
				new Multilingual.Value(english, "Play"))),
			new CategoryNameAndId("2", new Multilingual(
				new Multilingual.Value(english, "Swings"))),
			new CategoryNameAndId("529", new Multilingual(
				new Multilingual.Value(english, "Swing Seats")))));

		product.SalesPrice = new MultiCurrency(
			new [] { new Money("DKK", 123), new Money("USD", 123)});
        product.ListPrice = new MultiCurrency(
			new [] { new Money("DKK", 321), new Money("USD", 321)});
		
		product.Data["ShortDescription"] = new Multilingual(
			new Multilingual.Value(english, "The short english description"));
		// Important to set this timestamp to the exact same value for all products 
		product.Data["ImportedAt"] = importTimestamp; 
		product.Data["MinimumAge"] = 4D;
		product.Data["InStock"] = true;
		product.Data["USPs"] = new string[] {
			"first usp", "second usp", "third usp"};
		
		// Add any additional fields you would want returned from Relewise

		List<ProductVariant> variants = new List<ProductVariant>();
		// Foreach variant of this product
		{
			// Variant Id only has to be unique within the product
			var variant = new ProductVariant("The variant id"); 
			variant.Data["Materials"] = new MultilingualCollection(
				english, new List<string> { "Wood", "Metal" });
			variant.Data["Colors"] = new MultilingualCollection(
				english, new List<string> { "Red", "Green" });
			variant.Data["PrimaryMaterial"] = new Multilingual(
				english, "Wood");
			variant.Data["PrimaryColor"] = new Multilingual(
				english, "Red");
			// Add any additional fields you would want returned from Relewise

			variants.Add(variant);
		}
		// Foreach variant END

		productUpdates.Add(new ProductUpdate(
			product, variants,
			productUpdateKind: ProductUpdate.UpdateKind.ReplaceProvidedProperties,
			variantUpdateKind: ProductUpdate.UpdateKind.ReplaceProvidedProperties,
			replaceExistingVariants: true)); 
			// Replace existing variants = true will delete all variants in Relewise
			// (for the listed products) not included in this update request.
	}
	// Foreach product END

	// If this is a full-import (not delta), disable all non-included products
	{
		var nonUpdatedProductsFilter = new FilterCollection(
			new ProductDataFilter("ImportedAt", new EqualsCondition(
				importTimestamp, negated: true)));
		productUpdates.Add(new ProductAdministrativeAction(
			Language.Undefined, Currency.Undefined, 
			nonUpdatedProductsFilter, 
			Relewise.Client.DataTypes.ProductAdministrativeAction.UpdateKind.Disable));
	}
	
	var updatedProductsFilter = new FilterCollection(new ProductDataFilter(
		"ImportedAt", new EqualsCondition(importTimestamp, negated: false)));
	productUpdates.Add(new ProductAdministrativeAction(
		Language.Undefined, Currency.Undefined, 
		updatedProductsFilter, 
		Relewise.Client.DataTypes.ProductAdministrativeAction.UpdateKind.Enable));
	
	// Send all product updates and actions as a single (or few) network request.
	// The client will automatically send batches of 1.000 items per network request, 
	// so you can pass as many as you like to the tracker.Track / TrackAsync method.
	return tracker.TrackAsync(productUpdates.ToArray());
}

Integrating and Updating Content with .NET

To get content into Relewise, follow the template laid out below. Be aware of different data types and when to use the correct one.

Add whatever fields are necessary for your integration to be useful for your search and/or recommendation requirements.

If you are unsure of what entity-actions to take, refer to our list of entity-actions.

csharp
async Task Main()
{
	// Copy dataset id + API key + server URL from 
	// my.relewise.com > Administration -> API Keys
	var tracker = new Tracker(new Guid("00000000-0000-0000-0000-000000000001"), 
	"your api key", "the server URL for the dataset");
	// This is the recommended "Push" method, for importing content data into Relewise.
	await FullContentUpdates(tracker); 
	// Note all methods have a synchronous as well as an asynchronous counterpart, 
	// e.g. Tracker.Track / Tracker.TrackAsync
}


private Task FullContentUpdates(ITracker tracker)
{
	// Create a timestamp to distinguish active and inactive entities
	// Read more at
	// https://docs.relewise.com/docs/developer/bestpractices/product-integration.html
	double importTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

	// Language can be any string and doesn't have to be a valid iso-standard.
	Language english = new Language("en"); 

	List<Trackable> contentUpdates = new List<Trackable>();

	// Foreach content element that needs to be imported, do the following:
	{
		// The Id should be the primary id of the content
		Content content = new Content("Content-ID-01"); 
		
		content.DisplayName = new Multilingual(new Multilingual.Value(
			// We only set the English translation in this example 
			// but more can be set by parsing more MultilingualValue 
			// to the Multilingual::create method.
			english, "The english display name")); 
		
		content.Data["ShortDescription"] = new Multilingual(new Multilingual.Value(
			// We only set the English translation in this example 
			// but more can be set by parsing more MultilingualValue 
			// to the Multilingual::create method.
			english, "The short english description")); 
		content.CategoryPaths.Add(new CategoryPath(
			new CategoryNameAndId("23", new Multilingual(
				new Multilingual.Value(english, "Outdoor"))),
			new CategoryNameAndId("372", new Multilingual(
				new Multilingual.Value(english, "Hiking")))));

		// Important to set this timestamp to the exact same value for all content 
		content.Data["ImportedAt"] = importTimestamp; 
		content.Data["ReadingTimeInMinutes"] = 3;
		content.Data["News"] = true;
		content.Data["Badges"] = new string[] {
			"fun", "current season", "some other badge"};
			
		// Add any additional fields you would want returned from Relewise

		contentUpdates.Add(new ContentUpdate(
			content,
			kind: ContentUpdate.UpdateKind.ReplaceProvidedProperties)
		);
	}
	// Foreach content element END

	// If this is a full-import (not delta),
	// disable all non-included content elements
	{
		var nonUpdatedContentFilter = new FilterCollection(new ContentDataFilter(
			"ImportedAt", new EqualsCondition(importTimestamp, negated: true)));
		contentUpdates.Add(new ContentAdministrativeAction(Language.Undefined, 
		Currency.Undefined, 
		nonUpdatedContentFilter, 
		Relewise.Client.DataTypes.ContentAdministrativeAction.UpdateKind.Disable));
	}
	
	var updatedContentFilter = new FilterCollection(new ContentDataFilter(
		"ImportedAt", new EqualsCondition(importTimestamp, negated: false)));
	contentUpdates.Add(new ContentAdministrativeAction(Language.Undefined, 
	Currency.Undefined, 
	updatedContentFilter, 
	Relewise.Client.DataTypes.ContentAdministrativeAction.UpdateKind.Enable));
	
	// Send all content updates and actions as a single (or few) network request.
	// The client will automatically send batches of 1.000 items per network request, 
	// so you can pass as many as you like to the tracker.Track / TrackAsync method.
	return tracker.TrackAsync(contentUpdates.ToArray());
}

Don't know us? Don't worry - you can find more information about us, by visiting our main page www.relewise.com