EPiServer  /  Find October 03, 2011

Introducing Truffler – Advanced search made easy

NOTE Since writing this post the company behind Truffler, 200OK, has been sold to EPiServer and the product Truffler has been renamed to EPiServer Find. Most of the content of this blog post is however applicable to EPiServer Find as well. For questions regarding Find, be sure to visit the forum on EPiServer World.

Search engines are powerful. Truffler is a search solution that helps .NET developers leverage that power. Easily. While having fun.

Last week during a presentation at a user group I showed the project that me and my two partners Henrik Lindström and Marcus Granström have been working on for quite a while now – Truffler. Truffler is a search engine that we offer both as Software as a Service and as dedicated servers for rent. It’s a commercial product but we offer free trial indexes as well as personal indexes to developers that want to use it for their blogs or hobby projects as long as they link to us.

At it’s core Truffler is hosted ElasticSearch. For those who don’t know ElasticSearch it’s a highly scalable open source search engine built on top of Lucene founded by Shay Banon. And it’s simply amazing! We take care of configuration, security and add some additional features, most of which we’ll present during the coming months. We also enforce some conventions and restrictions thanks to which we can offer a, in my opinion, great development experience.

.NET API

But Truffler is also our client API for .NET. Truffler’s REST API is by no means limited to usage from .NET, but we realized that by combining ElasticSearch’s API that indexes JSON documents with concepts such as static reflection and expression trees in C# we could build something that would solve many problems that we ourselves have often encountered. And put the developer in the driving seat when it comes to search and querying.

The .NET API is built on the concept of convention over configuration, meaning that it should “just work” out of the box (no mapping, no configuration other than an API key and an index name) while offering developers the possibility to customize it’s behavior (through code) in just about any imaginable way to fit their needs should they need to. This is particularly important for us as we figure that most of its usage will be to index and search data that isn’t tailored for Truffler but instead comes from existing, often third party systems such as CMSes, product catalogs and CRMs. In fact, building such integrations will be the next step for us and a module for EPiServer CMS is already in the making.

The pitch

Using the .NET API you can index any .NET/CLR object including any nested object it has as properties. With a couple of lines of code at startup you can also index the return value of methods invoked on it.

After having indexed an object you can get it by ID, update it and delete it. And of course search for it. In all it’s properties or in a few specific properties with the ability to boost the relevance of matches in some of them. Of course with multi language support (you know, stemming and such).

And yes, you search in a strongly typed way with support for inheritance.

But you’re not limited to search. You can also do exact queries by applying filters much like you’d do with LINQ. Meaning that you can A) implement all those category, tag and author filters that the business wants on the search page much more easily and B) use it to solve other querying related problems that you might otherwise struggle with.

Thanks to the awesomeness of ElasticSearch, our conventions and functionality provided by the .NET API you can also implement geo search easily. And of course create facets (aggregate data) such as tag clouds and histograms.

Of course, since you push data to us rather than us crawling it every once in a while, the search is nearly real time and you have full control over what gets indexed and what doesn’t. As for security we offer those with a premium index SSL encryption, and of course those with the self-hosted version (In-a-box) can place the server(s) behind their own firewall.

Showing the complete functionality of the product in a blog post would make it a tad to long, but you are very welcome to check out our documentation (we’re working hard on expanding it). In the meantime, here’s a few examples.

var post = new BlogPost
{
    Title = "Best song ever!",
    Tags = new List<string> { "Rock", "Pop" },
    Author = new Author { Name = "Axl Rose", Id = 42 }
};

IClient client = Client.CreateFromConfig(); 
client.Index(post);
 
//So we've indexed it, that was hard work!
//Let's relax and do a full text search.
var query = client.Search<BlogPost>()
                  .For("rock");
 
//We really don't care about all the search stuff
//Let's just get the object
foreach (BlogPost hit in query)
{
    //...
}
 
//Let's only search in a few fields,
//and have some highlighting
query.InFields(x => x.Title, x => x.Tags)
    .WithHighlight(x => x.Title);
 
//This time we actually want some of the search fluff...
foreach (var hitItem in query.GetResult())
{
    //hitItem.Highlights
    //hitItem.Score
}
 
//Maybe filter a little as well?
query.Filter(x => x.Author.Name.Match("Axl"));
 
//That was a bit narrow wasn't it?
query.Filter(x => x.Author.Name.Match("Axl")
                | x.Tags.MatchCaseInsensitive("Rock"));
 
//But I don't want to retrieve the whole object from the service! Ok.
query.Select(x => new { x.Id, x.Title});
 
//Enough of this, update it!
post.Title = "One of the best songs ever";
client.Index(post);
 
//I'm tired, just delete it
client.Delete<BlogPost>(post.Id);

Great for AJAX

All Truffler indexes come with (at least) two API keys. One for both read and write access and one with read-only access. This means that given that you’re OK with someone potentially exploring your data you can built rich AJAX functionality without having to use your web servers as a proxy. And since ElasticSearch speaks JSON natively, building client side functionality is a breeze.

You’ll find a somewhat naïve example of using Javascript to both index and search for data in our documentation as well as an example of how to, really easily build autocomplete functionality.

Try it out and stay tuned

We’re continuously adding new features to both the REST API and the .NET client API and will also soon have our first integration module available. In the meantime, we’d love to hear feedback from the development community about what we can do better. After all, Truffler is all about helping developers build great search functionality with great cost efficiency for the business. So, go grab yourself a developer index!

PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.

Joel Abrahamsson

Joel Abrahamsson

I'm a passionate web developer and systems architect living in Stockholm, Sweden. I work as CTO for a large media site and enjoy developing with all technologies, especially .NET, Node.js, and ElasticSearch. Read more

Comments

comments powered by Disqus

My book

Want a structured way to learn EPiServer 7 development? Check out my book on Leanpub!

More about EPiServer Find