November Happy Hour will be moved to Thursday December 5th.

Mari Jørgensen
Feb 21, 2013
  6288
(1 votes)

Hidden Gems of EPiServer Find

EPiServer Find is not just for EPiServer CMS pages– in fact the client API supports indexing of any .NET object.

When working with indexing of data in EPiServer Find there are some hidden gems that are nice to know about.

The Id attribute: Avoid duplicates when updating

According to the documentation, If a document of the same type with the same ID already exists it will be overwritten (or updated if you like). In other words, controlling the ID is the key.

Let me illustrate this with a code sample. For demonstration purposes I have created a class Product:

public class Product
{
    public Guid Id { get; set; }
    public string DisplayName { get; set; }
    public string Description { get; set; }
    public string Brand { get; set; }
    public string Model { get; set; }
    public string Type { get; set; }
}

Using the Product model I can now add some simple test data to the EPiServer Find index.

Product p1 = new Product()
{
    Id = guidproduct1,
    DisplayName = "Cannondale CAAD 10",
    Model = "CAAD 10 Shimano 105",
    Description = "With its lightest-in-class frame and unmistakable Cannondale ride-feel," 
        + "the CAAD10 is designed to turn people into cyclists.",
    Brand = "Cannondale",
    Type = "Elite Racing Bikes"
};
 
Product p2 = new Product()
{
    Id = guidproduct2,
    DisplayName = "Cannondale Synapse Carbon 3",
    Model = "Carbon 3 Ultegra",
    Description = "Elite-race performance meets all-day comfort.",
    Brand = "Cannondale",
    Type = "Elite Racing Bikes"
};
 
var client = Client.CreateFromConfig();
client.Index(p1);
client.Index(p2);

If I navigate to the Find Explorer (from the main menu in EPiServer CMS) I can now see the following:

index_view_1

Notice the “Index ID” – this is the id that Find is using for identifying each document in the index. Lets see what happens if I now try to update product number two:

private static void UpdateItem()
{
    var client = Client.CreateFromConfig();
    // get product 2
    var searchResult = client.Search<Product>().
        Filter(p => p.Id.Match(guidproduct2))
        .GetResult()
        .FirstOrDefault();
 
    if (searchResult != null)
    {
        searchResult.Type = "Performance Road";
        client.Index(searchResult);
    }
}

index_view_2

As you can see from the screenshot above, the update resulted in duplicate documents in the index. Off course, I could solve this by deleting the document before re-indexing, but that far from an ideal solution. The trick is to use the Id attribute on the property that uniquely identifies your model:

[Id]
public Guid Id { get; set; }

Re-indexing, we can see that the Find is now using my Id property as Index ID:

index_view_3

This way updating existing documents no longer result in duplicates.

“Making it look pretty” - using IDocumentInterpreter

By default, Find will use Namespace_Class as title in the index explorer. To easier distinguish between the different documents, we can tell the explorer to use a property on our model instead. In order to do this, we create a new class where we implement interface IDocumentInterpreter and override the ExtendDocumentInformation method.

public class MyIndexInterpreter : IDocumentInterpreter
{
    public void ExtendDocumentInformation(IndexDocument indexDocument)
    {
        Expression<Func<Product, string>> headerExpression = 
            x => x.DisplayName;
        var headerField = SearchClient.Instance.Conventions.
            FieldNameConvention.GetFieldName(headerExpression);
        JToken headerToken;
        if (indexDocument.Hit.Document.TryGetValue(headerField, out headerToken))
        {
            indexDocument.Headline = headerToken.ToString();
        }
    }
}

Notice that you pass in your model type and specify the property you want to use as title – here I’m using DisplayName.

Navigating to the explorer view, it is a lot easier to distinguish between the documents in the index.

index_view_4

The IDocumentInterpreter interface is part of the EPiServer.Find.Framework.UI namespace.

Feb 21, 2013

Comments

Feb 21, 2013 10:20 PM

Good blog post for future reference.

Also very much like the road cycling reference! ;-)

Joel Abrahamsson
Joel Abrahamsson Feb 21, 2013 10:52 PM

Yay! You found IDocumentInterpreter! I owe you a beer next time I'm in Oslo!

Mari Jørgensen
Mari Jørgensen Feb 22, 2013 08:28 AM

@Joel: Actually the tip about IDocumentInterpreter came from my friends in EPiServer Norway :)

Henrik Lindström
Henrik Lindström Feb 25, 2013 09:13 AM

Great post! I'm just missing the "Canyon Ultimate CF" :-)

Per Magne Skuseth
Per Magne Skuseth Mar 1, 2013 09:54 AM

Nice post!
Note that after the [Id] attribute has been set, you can do a simple SearchClient.Instance.Get(id), instead of filtering.

@Joel: I think the tip about IDocumentInterpreter originated from you, so I guess you should buy yourself a beer :-)

Please login to comment.
Latest blogs
Optimizely SaaS CMS + Coveo Search Page

Short on time but need a listing feature with filters, pagination, and sorting? Create a fully functional Coveo-powered search page driven by data...

Damian Smutek | Nov 21, 2024 | Syndicated blog

Optimizely SaaS CMS DAM Picker (Interim)

Simplify your Optimizely SaaS CMS workflow with the Interim DAM Picker Chrome extension. Seamlessly integrate your DAM system, streamlining asset...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Optimizely CMS Roadmap

Explore Optimizely CMS's latest roadmap, packed with developer-focused updates. From SaaS speed to Visual Builder enhancements, developer tooling...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Set Default Culture in Optimizely CMS 12

Take control over culture-specific operations like date and time formatting.

Tomas Hensrud Gulla | Nov 15, 2024 | Syndicated blog

I'm running Optimizely CMS on .NET 9!

It works 🎉

Tomas Hensrud Gulla | Nov 12, 2024 | Syndicated blog

Recraft's image generation with AI-Assistant for Optimizely

Recraft V3 model is outperforming all other models in the image generation space and we are happy to share: Recraft's new model is now available fo...

Luc Gosso (MVP) | Nov 8, 2024 | Syndicated blog