Tuesday, June 21, 2011

Solr Search - Some Tips And Pointers

We've recently launched a huge project where we implemented Solr as the search platform. Even though Solr is quite easy to get started with, we've got a few tips and pointers to make life with Solr easier for you!

Know your configuration files

We had some initial trouble with the Solr configuration files, normally located under C:/solr/conf. The most important configuration files are solrconfig.xml and schema.xml.

  • In schema.xml, make sure the fields matches those you've defined in your application.
  • The config files are case sensitive! Make sure you spell copyField, multiValued etc correctly.
  • If you don't need elevation and have problems with configuration, try turning off the elevate.xml handler by uncommenting the appropriate lines in solrconfig.xml.

Improve performance by customizing solrconfig.xml

Solrconfig.xml holds a lot of fun stuff. Here you can setup Solr to improve the performance. If your hardware is up for it, that is.

Here are a few elements to get your started:

  • mergeFactor decides what size your index segments should have, thus either improving indexing or searching.
  • ramBufferSizeMB sets the amount of RAM available for Solr, before documents are flushed.
  • autoWarmCount may be used to pre-populate data from the search index.

Here's a great wiki page on Solr and performance, for further reading and available configuration options.

Use an absolutely unique key

You should define a unique key that will always be unique for a specific item in your Solr index. Either you assign this unique key an auto generated GUID, or you use Solr's built in UniqueKey field.

In schema.config, add the Solr UUID type:

<fieldType name="uuid" class="solr.UUIDField" indexed="true" />

Also add a field of the UUID type:

<field name="uid" type="uuid" indexed="true" stored="true"
default="NEW" />

Finally, point out the field as the unique key:



This was just some quick tips and pointers to get you more comfortable with Solr. More specifics on the project launch to come!

Thursday, June 16, 2011

Lansering av Sveriges charmigaste hem

Idag lanserade vi Fastighetsbyråns nya kampanjsajt http://www.sverigescharmigastehem.se/

En sida där alla kan vara med och tävla med 1-5 bilder på sin bostad. Vinnaren kan sedan stolt titulera sig ägare av Sveriges charmigaste hem.

Sajten är till skillnad från många av våra andra släpp inte byggd på EPiServer, utan baseras helt på Microsoft ASP.NET MVC 3 och Razor. Detta i kombination med ADO.NET Entity Framework 4.1 och en hel del JQuery har resulterat i en sajt med mycket ajaxfunktionalitet och en stor mängd integrationer mot diverse sociala medier. Bl.a. har vi inloggning via facebook, möjlighet att dela youtube-filmer och twitterflöden.

Vår systerbyrå Söderhavet har stått för designen och vi riktar ett stort tack för ett (återigen) mycket lyckat samarbete!

Projektgruppen från Nansens sida bestod av:
Projektledning och backend: Robert Linde
Frontend: Nansens senaste stjärnskott Giovanni Vivanco
Design och koncept: Mats Forsell(Söderhavet) och Anna Sandqvist(Söderhavet)

Monday, June 13, 2011

Mutiple brands in EPiServer Commerce

In EPiServer Commerce you map your products to a product template and your product listings to a product listing template this are then used to connect Commerce with EPiServer in the "CatalogPageProvider", all this is fine until you for example add a new catalog to Commerce that needs a different template then the default catalog.
This is what happened to us in our project when we added a new site with different design and product catalog into the EPiServer Commerce installation. To solve this problem we extended EPiServers CatalogPageProvider and did our own implementation of the function "GetPageType" that delivered different templates based on the catalog id of the page.

Here is our implementation of the GetPageType function,

public class AvalancheCatalogPageProvider : CatalogPageProvider
protected override string GetPageType(string key)
var store = new CommerceSiteMappingStore();
var dictionary = SplitKey(key);

int catalogId;
CommerceSiteMapping mapping;
if (int.TryParse(dictionary["CatalogId"], out catalogId) && (mapping = store.Find(catalogId)) != null)
var nodeType = (NodeType)Enum.Parse(typeof(NodeType), dictionary["NodeType"]);
switch (nodeType)
case NodeType.CatalogEntry:
return mapping.CatalogEntryPageType.Name;
case NodeType.CatalogNode:
return mapping.CatalogNodePageType.Name;
return mapping.FallbackPageType.Name;
return base.GetPageType(key);

private static IDictionary SplitKey(string key)
Dictionary dictionary = new Dictionary();
string[] strArray = MappedPPDB.SplitKey(key);
dictionary.Add("NodeId", strArray[0]);
dictionary.Add("CatalogName", strArray[1]);
dictionary.Add("ParentNodeId", strArray[2]);
dictionary.Add("CatalogId", strArray[3]);
dictionary.Add("NodeType", strArray[4]);
dictionary.Add("ID", strArray[5]);
dictionary.Add("ParentNodeCode", strArray[6]);
return dictionary;

The differences between this implementation and EPiServers is that we return different page types based on the catalog id of the page that is loading.
The mappings are saved in the dynamic data store and editable via a gui plugin in EPiServer, if we can't find a mapping that is configured in our tool we call EPiServers default implementation to let it handle the request.

As I said this is the solution for our project and the needs we had were each catalog is represented by only one page type.

Friday, June 10, 2011

A short summary of NDC 2011

For the last few days, 7 developers from Nansen Stockholm were attending the Norwegian Developers Conference in Oslo, Norway. The 3 days were jam-packed with great and inspirational talks covering a wide array of topics and technologies.

When selecting which talks to attend, I made a conscious choice of avoiding talks that seemed code-heavy as well as talks that seemed to cover to narrow of a field. Instead, I opted for talks that talked more of "why" instead of "how". I did this because in my experience, techy talks are usually much better when viewed on a computer so one can pause and reflect and digest what was being presented.

I started of with a talk by Robert C. Martin, also known as Uncle Bob and author of books like Clean Code and the newly released Clean Coder. He gave a magnificent talk about how programming languages have progressed through several paradigm shift and how we may have seen all types of languages that are going to exist. Given that, what would the final programming language look like? According to Uncle Bob - probably something like Clojure!

Next up were two talks about F# and functional programming from Amanda Laucher. Just like Uncle Bob, she believed that the future of computer programming lays in functional programming that is stateless and hence easily parallellizable.

Jon Skeet ended the day with Async 101, which is the new way to handle concurency in C# (5.0?). A bit tricky and not as elegant as the functional approach, but still much neater than todays solutions.

Day 2 started of with a double session from Stuart Sierra who gave us a very solid training in the basics and not-so-basics of Clojure. I took a real shine to this language and considering it runs on both the CLR and JVM I'm definatly going to check it out more.

Uncle Bob was up next, this time talking about monads in Clojure. This talk was great, Uncle Bob did a great job of explaining this incredibly dense topic in a straight-forward manner, but at the end of this session my brain was leaking out through my ears. What I took away from the talk was that monads can be used to allow functions that operate on a certain type to accept and completely different type (note: I could be completely wrong :)).

I had a great conference even if I wish I could fork() at times to go and see several sessions at once. Luckily all session were recorded and should be released on the NDC site soon!

Thursday, June 9, 2011

Roadmap for Episerver

At the last session of the 2011 North American Episerver Partner Summit (#episummit11) Bob Egner of Episerver presented a very interesting Product Roadmap.

The roadmap is for partner eyes only, but the strategy is based around a few points
  • Multi channel
  • Personalized content
  • Empower Content Contributors
  • Measure and Optimize
  • Development and Operational Enviroments
My take on this is that Episerver is really moving forward from being "just a cms" to a much more competent and comprehensive partner. All in all it the Episerver future looks fun and exciting!

Nansen goes Blodomloppet 2011

Igår var dagen B, Blodomloppet. Nansens första någonsin!
Vi var nio tappra själar från Nansen inklusive Samuel L från Söderhavet som begav sig ut. Trots stekande sol, promenerande tanter och allmän trängsel lyckades vi ta oss runt Djurgården.
Kalle P och Tomas (sprang med Christers lapp) vågade sig på 10km, vi andra safe:ade med 5km.

Robert P gjorde oss alla stolta genom sin 42a plats på 5km herrar!

Resultaten finns att skåda här:


Nu dagen efter har folk blivit pepp på fler lopp, det börjar redan viskas om Tjurruset i höst... vi får se!

På NDC ärallt bra

Bara då ni vet så har vi det bra här i norge. :-)

Wednesday, June 1, 2011

Web address prefix and CMS6

After upgrading one of our American clients site to CMS 6 we realized that the Url rewrite seems to have changed a bit when it comes to how the language web address prefix is handled.

In CMS5 you were still able to browse it by the lang code even if you had set an address prefix for the default lang (en). For example, if you had set the prefix to "english" you could reach the site with either www.mysite.com/en/ and www.mysite.com/english/.

In CMS6 it seem to overwrite the lang code so by setting the prefix to /english/ you would not be able to reach the site with /en/.

The breaking changes doesn't say anything about this though.