<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Search Nuggets &#187; fast</title>
	<atom:link href="http://blog.comperiosearch.com/blog/tag/fast/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.comperiosearch.com</link>
	<description>A blog about Search as THE solution</description>
	<lastBuildDate>Mon, 13 Jun 2016 08:59:45 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>Replacing FAST ESP with Elasticsearch at Posten</title>
		<link>http://blog.comperiosearch.com/blog/2015/03/20/elasticsearch-at-posten/</link>
		<comments>http://blog.comperiosearch.com/blog/2015/03/20/elasticsearch-at-posten/#comments</comments>
		<pubDate>Fri, 20 Mar 2015 10:00:52 +0000</pubDate>
		<dc:creator><![CDATA[Seb Muller]]></dc:creator>
				<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Comperio]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[elastic]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[geosearch]]></category>
		<category><![CDATA[Kibana]]></category>
		<category><![CDATA[logstash]]></category>
		<category><![CDATA[posten]]></category>
		<category><![CDATA[tilbudssok]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=3364</guid>
		<description><![CDATA[First, some background A few years ago Comperio launched a nifty service for Posten Norge, Norway&#8217;s postal service. Through the service, retail companies can upload their catalogues and seasonal flyers to make the products listed within searchable. Although the catalogue handling and processing is also very interesting, we&#8217;re going to focus on the search side [...]]]></description>
				<content:encoded><![CDATA[<h2>First, some background</h2>
<p>A few years ago Comperio launched a nifty service for <a title="Posten Norge" href="http://www.posten.no/">Posten Norge</a>, Norway&#8217;s postal service. Through the service, retail companies can upload their catalogues and seasonal flyers to make the products listed within searchable. Although the catalogue handling and processing is also very interesting, we&#8217;re going to focus on the search side of things in this post. As Comperio has a long relationship and a great deal of experience with <a title="FAST ESP" href="http://blog.comperiosearch.com/blog/2012/07/30/comperio-still-likes-fast-esp/">FAST ESP</a>, this first iteration of Posten&#8217;s <a title="Tilbudssok" href="http://tilbudssok.posten.no/">Tilbudssok</a> used it as the search backend. It also incorporated Comperio Front, our search middleware product, which recently <a title="Comperio Front" href="http://blog.comperiosearch.com/blog/2015/02/16/front-5-released/">had a big release. </a>.</p>
<h2>Newer is better</h2>
<p>Unfortunately, FAST ESP is getting on a bit and as a result Tilbudssok has been limited by what we can coax out of it. To ensure we provide the best possible search solution we decided it was time to upgrade and chose <a title="Elasticsearch" href="https://www.elastic.co/products">Elasticsearch</a> as the best candidate. If you are unfamiliar with Elasticsearch, take a moment to browse our other <a title="Elasticsearch blog posts" href="http://blog.comperiosearch.com/blog/tag/elasticsearch/">blog posts</a> on the subject. The resulting project had three main requirements:</p>
<ul>
<li>Replace Fast ESP with Elasticsearch while otherwise maintaining as much of the existing architecture as possible</li>
<li>Add geodata to products such that a user could find the nearest store where they were available</li>
<li>Setup sexy log analysis with <a title="Logstash" href="https://www.elastic.co/products/logstash">Logstash</a> and <a title="Kibana" href="https://www.elastic.co/products/kibana">Kibana</a></li>
</ul>
<p></br></p>
<h2>Data Sources, Ingestion and Processing</h2>
<p>The data source for the search system is a MySQL database populated with catalogue and product data. A separate Comperio system generates this data when Posten&#8217;s customers upload PDFs of their brochures i.e. we also fully own the entire data generation process.</p>
<p>The FAST ESP based solution made use of FAST&#8217;s JDBC connector to feed data directly to the search index. Inspired by <a title="Elasticsearch: Indexing SQL databases. The easy way." href="http://blog.comperiosearch.com/blog/2014/01/30/elasticsearch-indexing-sql-databases-the-easy-way/">Christoffers blog post</a>, we made use of the <a title="Elasticsearch JDBC River Plugin" href="https://github.com/jprante/elasticsearch-river-jdbc">JDBC plugin for Elasticsearch</a>. This allowed us to use the same SQL statements to feed Elasticsearch. It took us no more than a couple of hours, including some time wrestling with field mappings, to populate our Elasticsearch index with the same data as the FAST one.</p>
<p>We then needed to add store geodata to the index. As mentioned earlier, we completely own the data flow. We simply extended our existing catalogue/product uploader system to include a store uploader service. Google&#8217;s <a title="Google Geocoder" href="https://code.google.com/p/geocoder-java/">geocoder</a> handled converted addresses to coordinates for use with Elasticsearch&#8217;s geo distance sorting. We now had store data in our database. An extra JDBC river and another round of mapping wrestling got that same data into the Elasticsearch index.</p>
<h2>Our approach</h2>
<p>Before the conversion to Elasticsearch, the Posten system architecture was typical of most Comperio projects. Users interact with a Java based frontend web application. This in turn sends queries to Comperio&#8217;s search abstraction layer, <a title="Comperio Front" href="http://blog.comperiosearch.com/blog/2015/02/16/front-5-released/">Comperio Front</a>. This formats requests such that the system&#8217;s search engine, in our case FAST ESP, can understand them. Upon receiving a response from the search engine, Front then formats it into a frontend friendly format i.e. JSON or XML depending on developer preference.</p>
<p>&nbsp;</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/03/tilbudssok_architecture.png"><img class="size-medium wp-image-3422 aligncenter" src="http://blog.comperiosearch.com/wp-content/uploads/2015/03/tilbudssok_architecture-300x145.png" alt="Generic Search Architecture" width="300" height="145" /></a></p>
<p>Unfortunately, when we started the project, Front&#8217;s Elasticsearch adapter was still a bit immature. It also felt a bit over kill to include it when Elasticsearch has such a <a href="http://www.elastic.co/guide/en/elasticsearch/client/java-api/current/">robust Java API</a> already. I saw an opportunity to reduce the system&#8217;s complexity and learn more about interacting with Elasticsearch&#8217;s Java API and took it. With what I learnt, we could later beef up Front&#8217;s Elasticsearch adapter for future projects.</p>
<p>As a side note, we briefly flirted with the idea of replacing the entire frontend with a <a href="http://blog.comperiosearch.com/blog/2013/10/24/instant-search-with-angularjs-and-elasticsearch/">hipstery Javascript/Node.js ecosystem</a>. It was trivial to throw together a working system very quickly but in the interest of maintaining existing architecture and trying to keep project run time down we opted to stick with the existing Java based MVC framework.</p>
<p>After a few rounds of Googling, struggling with documentation and finally simply diving into the code, I was able to piece together the bits of the Elasticsearch Java API puzzle. It is a joy to work with! There are builder classes for pretty much everything. All of our queries start with a basic SearchRequestBuilder. Depending on the scenario, we can then modify this SRB with various flavours of QueryBuilders, FilterBuilders, SortBuilders and AggregationBuilders to handle every potential use case. Here is a greatly simplified example of a filtered search with aggregates:</p>
<script src="https://gist.github.com/92772945f5281df54c3b.js?file=SRBExample"></script>
<h2>Logstash and Kibana</h2>
<p>With our Elasticsearch based system up ready to roll, the next step was to fulfil our sexy query logging project requirement. This raised an interesting question. Where are the query logs? As it turns out, (please contact us if we&#8217;re wrong), the only query logging available is something called <a title="Slow Log" href="http://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-slowlog.html">slow logging</a>. It is a shard level log where you can set thresholds for the query or fetch phase of the execution. We found this log severely lacking in basic details such as hit count and actual query parameters. It seemed like we could only track query time and the query string.</p>
<p>Rather than fight with this slow log, we implemented our own custom logger in our web app to log salient parts of the search request and response. To make our lives easier everything is logged as JSON. This makes hooking up with <a title="Logstash" href="http://logstash.net/">Logstash</a> trivial, as our logstash config reveals:</p>
<script src="https://gist.github.com/43e3603bd75fd549a582.js?file=logstashconf"></script>
<p><a title="Kibana 4" href="http://blog.comperiosearch.com/blog/2015/02/09/kibana-4-beer-analytics-engine/">Kibana 4</a>, the latest version of Elastic&#8217;s log visualisation suite, was released in February, around the same time as we were wrapping up our logging logic. We had been planning on using Kibana 3, but this was a perfect opportunity to learn how to use version 4 and create some awesome dashboards for our customer:</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/03/kibana_query.png"><img class="aligncenter size-medium wp-image-3444" src="http://blog.comperiosearch.com/wp-content/uploads/2015/03/kibana_query-300x169.png" alt="kibana_query" width="300" height="169" /></a></p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/03/kibana_ams.png"><img class="aligncenter size-medium wp-image-3443" src="http://blog.comperiosearch.com/wp-content/uploads/2015/03/kibana_ams-300x135.png" alt="kibana_ams" width="300" height="135" /></a></p>
<p>Kibana 4 is wonderful to work with and will generate so much extra value for Posten and their customers.</p>
<h2>Conclusion</h2>
<ul>
<li>Although the Elasticsearch Java API itself is well rounded and complete, its documentation can be a bit frustrating. But this is why we write blog posts to share our experiences!</li>
<li>Once we got past the initial learning curve, we were able to create an awesome Elasticsearch Java API toolbox</li>
<li>We were severely disappointed with the built in query logging. I hope to extract our custom logger and make it more generic so everyone else can use it too.</li>
<li>The Google Maps API is fun and super easy to work with</li>
</ul>
<p>Rivers as a data ingestion tool have long been marked for deprecation. When we next want to upgrade our Elasticsearch version we will need to replace them entirely with some other tool. Although Logstash is touted as Elasticsearch&#8217;s main equivalent of a connector framework, it currently lacks classic Enterprise search data source connectors. <a title="Apache Manifold" href="http://manifoldcf.apache.org/">Apache Manifold</a> is a mature open source connector framework that would cover our needs. The latest release has not been tested with the latest version of Elasticsearch, but it supports versions 1.1-3.</p>
<p>Once the solution goes live, during April, Kibana will really come into its own as we get more and more data.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2015/03/20/elasticsearch-at-posten/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Dynamic search ranking using Elasticsearch, Neo4j and Piwik</title>
		<link>http://blog.comperiosearch.com/blog/2014/02/05/dynamic-search-ranking-using-elasticsearch-neo4j-and-piwik/</link>
		<comments>http://blog.comperiosearch.com/blog/2014/02/05/dynamic-search-ranking-using-elasticsearch-neo4j-and-piwik/#comments</comments>
		<pubDate>Wed, 05 Feb 2014 14:49:52 +0000</pubDate>
		<dc:creator><![CDATA[Christian Rieck]]></dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[dynamic rank tuning]]></category>
		<category><![CDATA[dynamic search ranking]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[enterprise search]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[neo4j]]></category>
		<category><![CDATA[Piwik]]></category>
		<category><![CDATA[rank tuning]]></category>
		<category><![CDATA[ranking]]></category>
		<category><![CDATA[search ranking]]></category>
		<category><![CDATA[Solr]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=1957</guid>
		<description><![CDATA[Getting the correct result at the top of your search results isn’t easy. Anyone working within search quickly realizes this. Tuning the underlying ranking model is a job that just doesn’t end. There is an entire profession about search engine optimization, making sure your site gets as high as possible on Google (and Bing, I [...]]]></description>
				<content:encoded><![CDATA[<div>
<p>Getting the correct result at the top of your search results isn’t easy. Anyone working within search quickly realizes this. Tuning the underlying ranking model is a job that just doesn’t end. There is an entire profession about search engine optimization, making sure your site gets as high as possible on Google (and Bing, I guess). If it is not the top result on Google, it is somehow your fault and not Google&#8217;s.<span id="more-1957"></span></p>
</div>
<div>
<p><strong>Nobody optimizes for an internal enterprise search solution</strong></p>
</div>
<div>
<p>If your document is not the top result in the internal search solution it is somehow the search engine&#8217;s fault, not yours. There is no link cardinality on a file system. All the metadata is wrong and the document your user is trying to find doesn’t even contain the words the user remembers it to contain; the end result being that the target document is not found. As a result of this, trust in the enterprise search diminishes and soon you are left without users. Let’s see how we can use <a title="Piwik" href="http://piwik.org">Piwik</a>, <a title="neo4j" href="http://www.neo4j.org">neo4j </a>and <a title="Elasticsearch" href="http://www.elasticsearch.org">Elasticsearch </a>to remedy this. (Yes, you can use <a title="Solr" href="http://lucene.apache.org/solr/">Solr</a> if you want).</p>
</div>
<div>
<p>This post is made up of three parts. First I’ll talk about gathering the data necessary. Then we’ll tackle getting the ‘right’ documents at the top of your search and lastly we’ll see if we can expand documents with words your users recalls  them by, but are not part of the documents themselves. The journey will be based on the work performed on Comperio’s internal search, at the moment implemented on an old Fast ESP installation.</p>
</div>
<div>
<p><strong>Gathering data</strong></p>
</div>
<div>
<p>First you need to know what your users are searching for and what they end up clicking on. We use Piwik, an open source web analytics platform, for this. Seeing the searches, modifications to the searches and if they ended up clicking on anything that they thought was exciting. For a while we only used this for statistics since Piwik offered better insight than the built in query statistics in Fast ESP. Here is an example of one search session:</p>
</div>
<div></div>
<div>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/piwik.png"><img class="alignnone size-full wp-image-1968" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/piwik.png" alt="" width="411" height="179" /></a></p>
<p>We see a user entering the site, querying ‘rank order words’ and clicking on a document. Then the same search is executed again. It is reasonable to conclude the clicked document did not contain the wanted information. Lastly ‘boost position term’ is searched. Sadly the session does not end with a click so I guess our search couldn’t deliver. :( [1]</p>
</div>
<div>
<p>In their current form, the statistics aren’t very useful. But what were to happen if we took these chains of activities and created a graph? We used neo4j for this. A small Java program was written to download the Piwik-history as an XML-file and insert it into a newly created neo4j database.</p>
</div>
<div>
<p>The nodes are either the start of a session, a search or a document. They are linked by relationships such as CLICKED, SEARCHED, RETURNED_FROM.  Since a neo4j database isn’t very screen shot friendly, here is a part of the graph as rendered by <a title="Gephi" href="https://gephi.org">Gephi</a>:</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/chinese.png"><img class="alignnone size-full wp-image-1964" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/chinese.png" alt="" width="411" height="141" /></a></p>
</div>
<div></div>
<div>
<p>We see someone looking for help with Chinese query suggestions. S361 marks the beginning of this session and the first search term was ‘chinese’. They then clicked a link for an internal mail archive before refining their search to ‘chinese als’ and so forth. Links that show when a user back tracked are not shown. That was an isolated little island. The more central documents and search terms at your company will create bigger webs.</p>
</div>
<div>
<p> <a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/web.png"><img class="alignnone size-full wp-image-1971" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/web.png" alt="" width="605" height="368" /></a></p>
</div>
<div></div>
<div>
<p>Seeing your search history organized like this should give an urge to dive in and explore. It is really interesting, fun and recommended!</p>
</div>
<div>
<p><strong>Finding popular documents</strong></p>
</div>
<div>
<p>The simplest way of finding the popular documents is to track search term -&gt; clicks directly. It is also the most common way of doing it. That wouldn’t utilize our fancy new graph now, would it? Since we can do queries against the database let’s get all search sessions of 8 or less actions that resulted in a click on document X:</p>
<p>&nbsp;</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/query.png"><img class="alignnone size-full wp-image-1969" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/query.png" alt="" width="605" height="40" /></a></p>
</div>
<div></div>
<div>
<p>Page Break(Small disclaimer: As my neo4j skills are very rudimentary there might be more efficient ways of doing this.)</p>
</div>
<div>
<p>Now we iterate over all sessions and give a score to each search term. The closer it is to the clicked document, the higher score it gets. Sum the score across all sessions.  After doing that you get a score indicating how ‘close’ a search term is to any document. This is example data for the single-word search term ‘vpn’:</p>
<p>&nbsp;</p>
</div>
<div><a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/json.png"><img class="alignnone size-full wp-image-1966" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/json.png" alt="" width="605" height="66" /></a></div>
<div>
<p>&nbsp;</p>
<p>When the score passes a threshold we add the search-document pair to an Elasticsearch index. For every search executed at our search we first check Elasticsearch to see if the term is boosted. For ‘vpn’ the search logs state</p>
</div>
<div></div>
<div>
<p> <a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/log.png"><img class="alignnone size-full wp-image-1967" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/log.png" alt="" width="605" height="50" /></a></p>
</div>
<div>
<p>&nbsp;</p>
<p>We can see how three documents are boosted for ‘vpn’. (By choice we only boost the top three). Using Fast ESP we wrap the original query with boosts for those specific documents.</p>
</div>
<div></div>
<div>
<p> <a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/fql.png"><img class="alignnone size-full wp-image-1965" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/fql.png" alt="" width="546" height="179" /></a></p>
</div>
<div>
<p>&nbsp;</p>
<p>In FAST ESP, as well as in Sharepoint Search 2013 the beloved xrank-operator is your friend. In a Lucene based search application use boost queries for this.</p>
</div>
<div>
<p>The search result returns the popular hits (only one shown here) at the top</p>
</div>
<div></div>
<div>
<p> <a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/topdoc.png"><img class="alignnone size-full wp-image-1970" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/topdoc.png" alt="" width="605" height="105" /></a></p>
</div>
<div>
<p>&nbsp;</p>
<p>The ugly star and cheesy feedback is me trying to tell the users rather bluntly that things happened behind the scene and that their actions will affect future searches. Currently there is no way of giving negative feedback to say ‘no, this is actually not a good hit’. Oh well.</p>
</div>
<div>
<p>As a bonus all terms that results in boosted documents are, as far as we know, smart things to search for and free of spelling errors. Therefor all such terms are added to a second Elasticsearch index we base our query completion on. (As a side note – if misspelled terms appear often enough to overcome the threshold for them to be taken into account, they could be part of your organization’s tribal language. If the users choose to spell the term “definately” so often that it “makes the cut” then the system should adapt to that. )</p>
</div>
<div>
<p><strong>Expanding documents to increase recall</strong></p>
</div>
<div>
<p>Often a user thinks of one document and searches for what, to them, identifies the document. That term might or might not be present in the document itself. If it doesn’t the document is not returned and the user becomes sad. Hopefully they alter their search and continue to look. Should they end up at their document we have the tools needed to remedy the situation. Here is a concrete example:</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2014/02/arch.png"><img class="alignnone size-full wp-image-1963" src="http://blog.comperiosearch.com/wp-content/uploads/2014/02/arch.png" alt="" width="594" height="217" /></a></p>
</div>
<div></div>
<div>
<p>Here we can see that the node marked 1 might be tagged with ‘sort order refiner entries’ or at least ‘refiner’, a term used twice when trying to find this document. (As an interesting side note, if you observe a lot of ‘sort X’ followed by ‘sort Y’ you might consider adding a synonym between X and Y.) If a term or phrase is used often enough across different sessions we save this to an Elasticsearch index. Each time a document is indexed we look up the document in our index and add any popular search terms to a low ranking field. This guarantees a recall of the document but it will not automatically top the results for those queries. This is a two-step process. If your search engine supports partial updates of documents, go with that.</p>
</div>
<div>
<p>Before adding the last step we noticed that for some searches we boosted documents that didn’t get recalled and thus were never displayed to the user even though we knew it was a good hit!</p>
</div>
<div>
<p><strong>Closing words</strong></p>
</div>
<div>
<p>As a first step towards dynamic ranking this has shown good results. As long as your search engine supports query time boosting you can implement this.</p>
</div>
<div>
<p><strong>By the way</strong></p>
</div>
<div>
<p>It should be noted that SharePoint will actually do some of this for you. It comes with an interface meant to be used by an end user (as opposed to all search engines I’ve seen) and the UI contains the event listeners on all links, tracking what you do. This is fed into a database and the data does affect ranking. As far as I know only the last search term before a click is associated with the clicked link.</p>
</div>
<div>
<p>[1] One scenario that Piwik and click tracking does not pick up is if the sought information is found in the returned teasers. Search sessions that don’t end in a click might in fact have a happy ending.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2014/02/05/dynamic-search-ranking-using-elasticsearch-neo4j-and-piwik/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Once upon a time, there was a company called FAST&#8230;</title>
		<link>http://blog.comperiosearch.com/blog/2013/04/01/once-upon-a-time-there-was-fast/</link>
		<comments>http://blog.comperiosearch.com/blog/2013/04/01/once-upon-a-time-there-was-fast/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 21:55:20 +0000</pubDate>
		<dc:creator><![CDATA[Marcus Johansson]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[ESP]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[fs4sp]]></category>
		<category><![CDATA[SP2013]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=1293</guid>
		<description><![CDATA[…that came out of nowhere, worked its way to the top, and then all of a sudden earlier this year disappeared for good. Time has come to say farewell. In my previous blog post, Examining the new search core in SharePoint 2013, I attached a presentation on Slideshare. The first few slides summarized FAST&#8217;s product [...]]]></description>
				<content:encoded><![CDATA[<p><strong>…that came out of nowhere, worked its way to the top, and then all of a sudden earlier this year disappeared for good. Time has come to say farewell.</strong></p>
<p><span id="more-1293"></span></p>
<p>In my previous blog post, <a href="http://blog.comperiosearch.com/blog/2013/03/06/examining-the-new-search-core-in-sharepoint-2013/">Examining the new search core in SharePoint 2013</a>, I attached a presentation on <a href="http://www.slideshare.net/comperio/axceler-webinar-feb2013-examining-the-new-search-core-in-sp2013">Slideshare</a>. The first few slides summarized FAST&#8217;s product history, both before and after it was acquired by Microsoft. I also boldly stated that we&#8217;re seeing the “End of an era, the birth of a new age”. As cheesy as it may sound, at least from a technology perspective, I find this to be very true.</p>
<p>FAST Search and Transfer, the Norwegian company that sprung from the university in Trondheim, was founded as early as 1997. That&#8217;s a staggering 16 years ago. Even 4 years before the initial release of SharePoint.</p>
<p>Although it&#8217;s debatable when FAST initially entered the Enterprise Search market, the first release of FAST Data Search (FDS) was certainly a milestone. Much later, Microsoft acquired FAST and snapped up its hugely successful successor, the Enterprise Search Platform (ESP). It was later turned into the products FSIA/FSIS and also served as the backbone for FAST Search Server 2010 for SharePoint (FS4SP).</p>
<p>One thing that strikes me when reminiscing about FAST, is how the technology stack can be traced throughout its history. Many of the internal FAST processes we saw in FS4SP were actually already introduced back in FDS (of course in varying shape and form). But like I said in my last blog post, the idea that “FAST is now fully integrated” in SharePoint 2013 is just… well, wrong. The “technology trace” is now gone.</p>
<p>The figure below outlines FAST&#8217;s product history. As you can see, FS4SP was a merge between the FAST and the SharePoint worlds. And it showed. A Microsoft technician, who shall remain unnamed, once referred to it as the “bastard child of the two paradigms”. Although a little harsh – FS4SP was arguably a great improvement to the search-deprived SharePoint world – there was certainly some truth to it.</p>
<p align="center"><a href="http://blog.comperiosearch.com/wp-content/uploads/2013/03/The-evolution-of-FAST.png"><img title="The evolution of FAST" src="http://blog.comperiosearch.com/wp-content/uploads/2013/03/The-evolution-of-FAST_thumb1.jpg" alt="The evolution of FAST" border="0" /></a></p>
<p>Eventually, with the arrival of SharePoint 2013, Microsoft released a well-tailored and cohesive search experience. But there was no longer an obvious technical inheritance from the earlier FAST product line, which is why SharePoint 2013 isn&#8217;t about having FAST “fully integrated”. It&#8217;s, simply put, a whole new platform. Of course with a few exceptions, e.g. some functionality from FSIS carried over to the new release. But generally speaking, we&#8217;re looking at a completely new platform, rewritten from the ground up.</p>
<p>In other words, the pre-MS technology is no longer around and the “technology trace” that we saw in earlier products is now cut off. Additionally, the “FAST” trademark has now slowly started the process of fading into obscurity.</p>
<p>All said and done, it&#8217;s only appropriate that FAST – the company, its technology and the trademark – is finally given a proper farewell. Without further ado, I give you its obituary: FAST, may you rest in peace, among friends in Enterprise Software heaven.</p>
<p align="center"><img title="FAST obituary" src="http://blog.comperiosearch.com/wp-content/uploads/2013/03/FAST-obituary.png" alt="FAST obituary" border="0" /></p>
<p align="left">(Sorry, just couldn&#8217;t help but to shamelessly plug Comperio&#8217;s consulting services <img src="http://blog.comperiosearch.com/wp-content/uploads/2013/03/smile3.gif" alt="" />)</p>
<div class="bjtags">Tags: <a href="http://technorati.com/tag/FAST" rel="tag">FAST</a>, <a href="http://technorati.com/tag/ESP" rel="tag">ESP</a>, <a href="http://technorati.com/tag/FS4SP" rel="tag">FS4SP</a>, <a href="http://technorati.com/tag/SP2013" rel="tag">SP2013</a></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2013/04/01/once-upon-a-time-there-was-fast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making your Fast Search for SharePoint-life easier with ElasticSearch.</title>
		<link>http://blog.comperiosearch.com/blog/2012/11/13/making-your-fast-search-for-sharepoint-life-easier-with-elasticsearch/</link>
		<comments>http://blog.comperiosearch.com/blog/2012/11/13/making-your-fast-search-for-sharepoint-life-easier-with-elasticsearch/#comments</comments>
		<pubDate>Tue, 13 Nov 2012 11:26:56 +0000</pubDate>
		<dc:creator><![CDATA[Christian Rieck]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[crawl log]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=1155</guid>
		<description><![CDATA[Last week we were trying to track down a document that, based on customer feedback, must have been lost somewhere between the content source and the index. By turning on the Fast Pipeline stage FFDdumper and doing a full crawl we determined that the document at least had made it to the FAST pipeline. Our [...]]]></description>
				<content:encoded><![CDATA[<p>Last week we were trying to track down a document that, based on customer feedback, must have been lost somewhere between the content source and the index. By turning on the Fast Pipeline stage FFDdumper and doing a full crawl we determined that the document at least had made it to the FAST pipeline. Our third party connector did its job and the blame was either on SharePoint or Fast. The next step was to inspect SharePoint’s crawl logs. They look like this:</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2012/11/crawllog2.png"><img class="alignnone size-full wp-image-1161" src="http://blog.comperiosearch.com/wp-content/uploads/2012/11/crawllog2.png" alt="" width="1002" height="57" /></a></p>
<p>In this example I have simply crawled the c: drive on my virtual machine with SharePoint to generate some entries in the crawl log. 269 errors aren’t that many; you could click the link and inspect the log manually in a reasonable amount of time. Viewing the logs will let you inspect 50 documents at a time.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2012/11/crawllog1.png"><img class="alignnone  wp-image-1160" src="http://blog.comperiosearch.com/wp-content/uploads/2012/11/crawllog1-1024x259.png" alt="" width="614" height="155" /></a></p>
<p>&nbsp;</p>
<p>This gets boring really fast. Therefore we started to use the API for extracting crawl logs from SharePoint [3] programmatically. Because of the API’s deprecated status the documentation is a bit on the thin side. Luckily there are some examples in the blogosphere [1,2] that helped us along and we could soon dump the crawl logs to file and ctrl-f for our missing document. Of course, the script could find the log entry and only show you the relevant one. However with a large crawl log it can take hours to extract all the log entries. It is better to dump them all to file should you need to look for a second or third file later.</p>
<p>Using grep, findstr or ctrl-f for searching feels wrong when you work as a search consultant. Instead the natural instinct when something large should be searched through is to index it. One option was to index it back into SharePoint through BDC (and get a possible nasty loop with reading and creating logs) or to use the old Fast API directly, bypassing SharePoint. Both felt a little heavy duty for this one-off job, and that’s when we put ElasticSearch to play. ElasticSearch is a fairly new search engine built on Lucene, and sometimes referred to as “The new kid on the block” in the Open Source Community where there’s some friendly rivalry between the Solr and ElasticSearch camps. It is a 20MB download and is ready to index documents mere seconds after you unzip the package. To index a document you simply POST some JSON to a REST endpoint and that is it. With so many libraries offering JSON-serialization and REST calls, building the world’s simplest connector doesn’t take long. We ported the old PowerShell script to C# and added 30 lines of code. With the removal of file creation code we actually reduced the lines of code overall. The indexing specific part of the script looks like this:</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2012/11/script.png"><img class="alignnone  wp-image-1159" src="http://blog.comperiosearch.com/wp-content/uploads/2012/11/script-1024x480.png" alt="" width="614" height="288" /></a></p>
<p>All we do is populate a little DTO, serialize it and push it to ElasticSearch. The indexing takes very little time, in fact fetching the logs from SharePoint is the slowest part of the connector. Notice that the call to index the document isn’t even done asynchronously. After indexing some data and indexing the logs ElasticSearch-head[4] is the easiest way to have a look. The tab “Structured Query” lets you create queries without any prior knowledge of the query syntax. As an example, here I have queried for all failing txt files in the log. (Some parts of the screen shot was dropped to make the image fit the page).</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2012/11/elasticresult.png"><img class="alignnone  wp-image-1157" src="http://blog.comperiosearch.com/wp-content/uploads/2012/11/elasticresult-1024x249.png" alt="" width="614" height="149" /></a></p>
<p>If you have a lot of failures in your SharePoint crawl log it makes sense to start with your most common cause of error. In the API each log entry has a property called ErrorId, although StatusCode would be a more fitting name (In PowerShell it seems to be called ErrorId and in C# MessageId). So in order to get the most common cause for errors one should look at the distribution of ErrorIds. In Fast Search for SharePoint this could be done by placing the ErrorIds in a managed property and configure it with the refiner property, effortlessly producing the distribution of ErrorIds. In ElasticSearch you specify refiners, called facets, at query time. In my limited test case the distribution looks like this:</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2012/11/Facets.png"><img class="alignnone  wp-image-1158" src="http://blog.comperiosearch.com/wp-content/uploads/2012/11/Facets.png" alt="" width="485" height="514" /></a></p>
<p>It is clear that ErrorId 0 is the most common followed by 5 and 748. What the specific ErrorIds mean is unfortunately not documented. The easiest is to query for log entries with an ErrorId and look at the error description. As mentioned ErrorId 0 means OK and 1 means deleted. All failures that happen in the Fast pipeline will be wrapped with ErrorId 11. One of the ErrorIds is simply a statement from SharePoint saying that a crawl rule was honored.<br />
Using this as a dashboard and thinking beyond a sample crawl, you could easily envision this being a tool for checking:</p>
<ul>
<li>How often and when a document was crawled</li>
<li>Does the crawler experience issues at certain times of the day</li>
<li>What crawl rates are the crawler able to sustain in the long run</li>
<li>What file suffixes are most prone to errors</li>
<li>What top level folders are the most troublesome to index</li>
</ul>
<p>&nbsp;</p>
<p>The code linked below should be seen as proof of concept. You are free to download and it and it will work. Some parameters on the SharePoint API-calls can surely be set better. ElasticSearch provides a bulk-update API that should be used when indexing large datasets. If you are running ElasticSearch on a non-standard port you need to change the code. Also note the complete lack of error handling.</p>
<p>What about that missing file? Turns out it was there all along. The customer was searching for the filename and didn’t recognize the second hit that was displaying his document’s title, not filename. Oh well.</p>
<p>1: http://blogs.msdn.com/b/spses/archive/2011/06/22/exporting-sharepoint-2010-search-crawl-logs.aspx<br />
2: http://blogs.msdn.com/b/russmax/archive/2012/01/28/sharepoint-powershell-script-series-part-5-exporting-the-crawl-log-to-a-csv-file.aspx<br />
3: http://msdn.microsoft.com/en-us/library/ms514229.aspx<br />
4: http://mobz.github.com/elasticsearch-head<br />
5: http://www.elasticsearch.org</p>
<p>&nbsp;</p>
<p>The script can be found here: <a href="http://blog.comperiosearch.com/wp-content/uploads/2012/11/Program.txt">Program.cs</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2012/11/13/making-your-fast-search-for-sharepoint-life-easier-with-elasticsearch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hot off the press &#8211; the FAST Search for SharePoint bible (co-authored by Comperio&#8217;s Marcus Johansson)</title>
		<link>http://blog.comperiosearch.com/blog/2012/04/26/hot-presses-fast-search-sharepoint-bible-co-authored-comperios-marcus-johannson/</link>
		<comments>http://blog.comperiosearch.com/blog/2012/04/26/hot-presses-fast-search-sharepoint-bible-co-authored-comperios-marcus-johannson/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 11:19:53 +0000</pubDate>
		<dc:creator><![CDATA[Enda Flynn]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[Comperio]]></category>
		<category><![CDATA[developers]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[Johansson]]></category>
		<category><![CDATA[learn]]></category>
		<category><![CDATA[Marcus]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Mikael]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[sharepoint]]></category>
		<category><![CDATA[solution]]></category>
		<category><![CDATA[Svenson]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://nuggets.comperiosearch.com/?p=890</guid>
		<description><![CDATA[Comperio consultant, Marcus Johansson, co-authors &#8216;Working with Microsoft FAST Search Server 2010 for SharePoint&#8217;. As most search techies will testify, the life of a consultant working on complex enterprise search projects with large customers, can be quite a demanding one. To commit to investing personal time, outside of all this project work is, to put [...]]]></description>
				<content:encoded><![CDATA[<p><img class="alignnone size-medium wp-image-891" title="FAST Search for SharePoint book - Marcus Johansson" src="http://blog.comperiosearch.com/wp-content/uploads/2012/04/FS4SP_book-cover-245x300.png" alt="" width="245" height="300" /></p>
<p>Comperio consultant, Marcus Johansson, co-authors &#8216;Working with Microsoft FAST Search Server 2010 for SharePoint&#8217;.</p>
<p>As most search techies will testify, the life of a consultant working on complex enterprise search projects with large customers, can be quite a demanding one. To commit to investing personal time, outside of all this project work is, to put pen to paper and document a series of learnings and tips in a structured and user-friendly format, is no mean feat. So on this note, we salute Comperio consultant <a href="http://blog.comperiosearch.com/author/mjohansson/" target="_blank">Marcus Johansson </a>and congratulate him on the release of his first book earlier this month - <a href="http://www.amazon.com/Working-Microsoft-Search-Server-SharePoint/product-reviews/0735662223/ref=dp_top_cm_cr_acr_txt?ie=UTF8&amp;showViewpoints=1" target="_blank">Working with Microsoft FAST Search Server 2010 for SharePoint</a>.</p>
<p>Marcus co-authored the book with Mikael Svenson and Robert Piddocke, who are also highly regarded contributors to the search community. Here, in Marcus&#8217; own words, is some background on the book:</p>
<p><em>The book is split into two parts: the first one explains what you&#8217;ll need to know to deploy and administrate a solution. The second one is targeting developers who want to build their own search solutions on top of FAST Search for SharePoint. Although we expect most readers to have a SharePoint background, people who&#8217;s worked with FAST technology in previous incarnations will hopefully feel at home as well.</em></p>
<p><em>Recognizing  FAST Search for SharePoint&#8217;s popularity, and seeing that the product is many people&#8217;s first exposure of Enterprise Search technology, the first two chapters introduce the reader to important concepts and terminology. We felt it was critical to get this backdrop right as there are vastly different data and user experience opportunities (and challenges) in Search technology, than in e.g. a database-driven solution.</em></p>
<p><em>The next few chapters  target the IT Pro audience and deal with such things as architecture, scale-out, deployment and security. Scaling, in particular, is covered in depth seeing how FAST Search for SharePoint is often used for top-tier solutions both in  query load and content volume. Additionally, day-to-day operations and the various methods of maintenance is covered in detail. We show you how to interact with and follow-up the system through the SharePoint GUI, but also how to work with the solutions through PowerShell and, for those adventurous people who wants to truly integrate the platform in their application environments, how you can integrate against FAST Search for SharePoint&#8217;s native APIs even for administrational and operational tasks.</em></p>
<p><em>The second part of the book is a good fit for application developers who want to create their own search solutions on top of FAST Search for SharePoint, whether that means extending a default FAST Search Center or completely build their own search-driven application truly taking advantage of the powerful platform. Doing so, developers will realize an Enterprise Search platform, such as FAST Search for SharePoint, relies not only on a competent and flexible index, but also on a framework for advanced content processing and the possibilities to query into the data using a rich query language.</em></p>
<p><em>Finally, the book is wrapped up with a tutorial-like section on how to resolve common problems and how to attack frequent development scenarios.</em></p>
<p><em>At Comperio, we see how more and more of our clients realize the potential in not only implementing a global search experience in their enterprise, but to deploy targeted search-driven applications across their organizations. One user group might need a mash-up of data aggregated from several internal content sources, and perhaps another group needs to trigger a certain function that he or she perceives as a single operation, but in reality hits 2-3 different source systems in the backend. A search-driven interface is the very sweet spot for building such applications, and  I&#8217;m hopeful this book will give you the tools of the trade to implement them in reality.</em></p>
<p><em>Happy reading!</em></p>
<p>In recognition of Marcus&#8217; achievement, the team here in Comperio have given him temporary clearance to use lines like <em>&#8216;As I say in my book, Working with Microsoft FAST Search Server 2010 for SharePoint, &#8230;&#8217; </em>in internal meetings and possibly even at customer presentations.</p>
<p>The book is now available for purchase on <a href="http://www.amazon.com/Working-Microsoft-Search-Server-SharePoint/product-reviews/0735662223/ref=dp_top_cm_cr_acr_txt?ie=UTF8&amp;showViewpoints=1" target="_blank">Amazon</a> - or you can win one of three free copies being offered by Comperio, by being one of the first to tweet this post mentioning @comperiosearch.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2012/04/26/hot-presses-fast-search-sharepoint-bible-co-authored-comperios-marcus-johannson/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hard Job Keeping Search Technology in Norway</title>
		<link>http://blog.comperiosearch.com/blog/2012/02/24/hard-job-keeping-search-technology-norway/</link>
		<comments>http://blog.comperiosearch.com/blog/2012/02/24/hard-job-keeping-search-technology-norway/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 10:35:15 +0000</pubDate>
		<dc:creator><![CDATA[Enda Flynn]]></dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Bjørn Olstad]]></category>
		<category><![CDATA[Comperio]]></category>
		<category><![CDATA[data explosion]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[enterprise search]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[jobfairy]]></category>
		<category><![CDATA[Jørn Ellefsen]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://nuggets.comperiosearch.com/?p=851</guid>
		<description><![CDATA[I found this interview (article from Nov. 2011) with the Director of Microsoft&#8217;s Enterprise Search Group, Bjørn Olstad on http://www.tu.no. Below is an English summary of the main points, along with some elbaorations. Dr. Olstad speaks on how Norway is a hotbed for search technology development and this search ecosystem has it&#8217;s source at NTNU in [...]]]></description>
				<content:encoded><![CDATA[<p>I found this interview (article from Nov. 2011) with the Director of Microsoft&#8217;s Enterprise Search Group, Bjørn Olstad on <a href="http://www.tu.no">http://www.tu.no</a>. Below is an English summary of the main points, along with some elbaorations.</p>
<p><img src="http://www.tu.no/migration_catalog/2011/09/26/tu2011092620110921-tu-microsoft-0154114_47_59-1109261356.jpg/alternates/w940/TU2011092620110921-TU-microsoft-0154114_47_59%201109261356.jpg" alt="tu.no bjorn olst" width="80%" /></p>
<p>Dr. Olstad speaks on how Norway is a hotbed for search technology development and this search ecosystem has it&#8217;s source at NTNU in Trondheim, which have been a feeder university to search giants like Yahoo, Google and Microsoft.</p>
<p>With the tidal growth of data (particularly unstructured) in the past decade, it is no surprise that enterprise search has seen impressive increases in levels of demand. Hence, says Dr. Olstad, the competition for bright young knowledge management or search graduates has intensified. He also points out that several search start-ups have risen out of Norway, benefitting from the knowledge and experience in the local search ecosystem.</p>
<p>One example of these Norwegian search start-ups is Comperio, which has matured to being 50 employees strong with offices in Oslo, Stockholm, London and Boston. Comperio is a Systems Integrator (SI) focused on implementing FAST Search projects for enterprise customers. These search solutions, more recently developed on the FAST Search for SharePoint platform, offer an alternative to traditional integration between IT systems. &#8216;Today, a lot of IT budgets devoted to integrating old and new solutions. It costs time and money. We rather use search technology&#8217;, says Comperio founder and CEO Jørn Ellefsen.</p>
<p>Comperio has developed search solutions in Norway for such recognisable names as, Sintef, Posten, DSS, DNV and Innovation Norway. Outside of Norway, Comperio has delivered large projects for the likes of UBS and Shell. &#8216;The search-based technology we are developing is largely generic, and it allows us to reuse the solutions from previous projects with new customers. This means that it is both cheaper and better for everyone. This market is starting to wake up in earnest and will grow quickly when you discover how effective the technology is. I think the market for our services will increase tenfold over the next three years&#8217;, added Ellefsen.</p>
<p>Comperio are currently hiring for their Oslo and London offices. See the open positions @ <a href="http://www.comperiosearch.com/about-comperio/work-for-us/">http://www.comperiosearch.com/about-comperio/work-for-us/</a>.</p>
<p>Original article from <a href="http://www.tu.no/it/article292738.ece">http://www.tu.no/it/article292738.ece</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2012/02/24/hard-job-keeping-search-technology-norway/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Document Thumbnails and PowerPoint Preview for your search results without installing FAST for SharePoint</title>
		<link>http://blog.comperiosearch.com/blog/2011/05/14/document-thumbnails-and-powerpoint-preview-for-your-search-results-without-installing-fast-for-sharepoint/</link>
		<comments>http://blog.comperiosearch.com/blog/2011/05/14/document-thumbnails-and-powerpoint-preview-for-your-search-results-without-installing-fast-for-sharepoint/#comments</comments>
		<pubDate>Sat, 14 May 2011 11:17:20 +0000</pubDate>
		<dc:creator><![CDATA[Mikael Svenson]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[fs4sp]]></category>
		<category><![CDATA[sharepoint]]></category>
		<category><![CDATA[sp2010]]></category>

		<guid isPermaLink="false">http://nuggets.comperiosearch.com/2011/05/document-thumbnails-and-powerpoint-preview-for-your-search-results-without-installing-fast-for-sharepoint/</guid>
		<description><![CDATA[[Originally posted at: http://techmikael.blogspot.com/2011/05/document-thumbnails-and-powerpoint.html] Microsoft offers three different flavors of search for SharePoint 2010: Foundation, Standard and Enterprise. For each level upwards you get more feature and better search capabilities. One of the visual features included with FAST for SharePoint is Thumbnails and Previews for the search results, as listed on the comparison table below (Compare [...]]]></description>
				<content:encoded><![CDATA[<p><em>[Originally posted at: <a title="Tech And Me" href="http://techmikael.blogspot.com/2011/05/document-thumbnails-and-powerpoint.html">http://techmikael.blogspot.com/2011/05/document-thumbnails-and-powerpoint.html</a>]</em></p>
<p>Microsoft offers three different flavors of search for SharePoint 2010: Foundation, Standard and Enterprise. For each level upwards you get more feature and better search capabilities. One of the visual features included with FAST for SharePoint is Thumbnails and Previews for the search results, as listed on the comparison table below (<a href="http://sharepoint.microsoft.com/en-us/buy/Pages/Editions-Comparison.aspx?Capability=Search">Compare SharePoint Editions – Search</a>).</p>
<p>Wouldn’t it be nice to have this feature on all versions of SharePoint? I will tell you how, as I demonstrated in a proof of concept talk at <a href="http://www.arcticsharepointchallenge.com/">Arctic SharePoint Challenge 2011</a>.</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="2011-04-28-Search-Thumbs-Preview-1" src="http://blog.comperiosearch.com/wp-content/uploads/2011/05/2011-04-28-Search-Thumbs-Preview-1.png" border="0" alt="2011-04-28-Search-Thumbs-Preview-1" width="504" height="410" /></p>
<p>The Thumbnail and Preview feature is depending on <a href="http://office.microsoft.com/en-us/web-apps/">Office Web Apps</a>, which is an additional module you can install on all versions of SharePoint 2010 in order to get web based editing capabilities of Office documents (Word, Excel, PowerPoint and OneNote). Office Web Apps itself is free, but requires Volume Licensing for Microsoft Office 2010.</p>
<p>The API’s used for generating the thumbnails and the PowerPoint previews are the <a href="http://download.microsoft.com/download/1/6/F/16F4E321-AA6B-4FA3-8AD3-E94C895A3C97/%5BMS-OMPWHP%5D.pdf">Office Mobile PowerPoint Web Handler Protocol</a> and the <a href="http://download.microsoft.com/download/1/6/F/16F4E321-AA6B-4FA3-8AD3-E94C895A3C97/%5BMS-OMWWH%5D.pdf">Office Mobile Word Web Handler Protocol</a>, both included with Office Web Apps. These API’s include functions to retrieve generated images of the documents as well as functions to retrieve the textual content within the documents. The API works for doc, docx, ppt and pptx files (Office 97-2010 formats).</p>
<p>The Word API is limited to generating a thumbnail for the first page in your document, while the PowerPoint API can generate an image of any slide as seen below.</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="2011-04-28-Search-Thumbs-Preview-2" src="http://blog.comperiosearch.com/wp-content/uploads/2011/05/2011-04-28-Search-Thumbs-Preview-2.png" border="0" alt="2011-04-28-Search-Thumbs-Preview-2" width="504" height="335" /></p>
<p>If you have installed the Enterprise version of SharePoint you have the possibility to create a new Search Center based on the “<em>FAST Search Center</em>” template, even though FAST is not installed.</p>
<p>The FAST Search Center template features XSLT in the Core Results Web Part which renders javascript calls to functions in a file called <em>search.js</em> located in the <em>_layouts</em> folder. Search.js further implements the communication with the mobile API’s to generate the images.</p>
<p>There are quite a few lines of javascript to implement this feature, but if you are a bit experienced with javascript and ajax programming you would be able to program this feature yourself. This will allow you to get thumbnails and PowerPoint previews with any version of SharePoint, from the free Foundation version to the Enterprise version.</p>
<p>If you are less handy with javascript you can copy out the XSLT used in the Core Results WebPart in the FAST Search Center site template, modify it some, and use it with a search site based on the “Enterprise Search Center” template instead. This way you will get additional visual improvements to the standard search page without having to install FAST.</p>
<p>The quick way is to replace some of the <em>xsl:params</em> set by the web part with pre-set variables instead. If you have FAST installed, then the parameters will be set via the Core Results Webpart. As we are using the oob search we have to set these parameters as variables instead.</p>
<p><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">OpenPreviewLink</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">&#8216;Preview&#8217;</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">ClosePreviewLink</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">&#8216;Close Preview&#8217;</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">ThumbnailTooltipLoadingFailed</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">&#8216;Loading failed!&#8217;</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">ThumbnailTooltipLoading</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">&#8216;Click to toggle preview&#8217;</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">AAMZone</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">0</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">PreviewWindowSize</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">160</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">EnableDocumentPreviewPowerPoint</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">&#8216;true&#8217;</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">EnableDocumentPreviewWord</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">&#8216;true&#8217;</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">ConcurrentDocumentPreview</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">10</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:variable</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">name</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">TotalDocumentPreview</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;"> </span></span><span><span style="color: #ff0000;">select</span></span><span><span style="color: #0000ff;">=</span></span><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">10</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;"> /&gt;</span></span></span></span></p>
<p>I also had to modify the xslt two more places. Around line 665 and line 725 locate the <em>FST_CheckForPreview</em> call and change the function parameter</p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;"> </span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: 'Envy Code R';"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"><span style="font-size: 9.5pt;">&#8216;&lt;</span></span></span><span style="font-size: 9.5pt;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #2b91af;">xsl:value-of</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;"> </span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #ff0000;">select</span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="color: #0000ff;">=</span></span></span><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-size: 9.5pt;"><span style="color: #000000;">&#8220;</span><span><span style="color: #0000ff;">sitename</span></span><span style="color: #000000;">&#8220;</span></span><span><span style="font-size: 9.5pt; color: #0000ff;">/&gt;&#8217;</span></span></span></span></p>
<p>with</p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-family: 'Envy Code R';"><span style="font-size: 9.5pt; color: #0000ff;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="mso-bidi-font-family: 'Envy Code R';"><span style="font-family: 'Envy Code R';"><span style="font-size: 9.5pt; color: #0000ff;">&#8216;http://rootsite&#8217;</span></span></span></p>
<p>where rootsite is the name of your SharePoint server url.</p>
<p>This was to ensure the calls to the Mobile API went to the top level site, as they failed when called on sub-site url’s.</p>
<p>That being said, there are several other good reasons for deploying FAST for SharePoint in your organization besides these visual enhancements. Capabilities to enrich and modify your content prior to indexing, thus tailoring search experience towards the real needs of your users, as well as the powerful query capabilities offered via FAST Query Language are just a couple of arguments for choosing FAST.</p>
<p>But then again, it never hurts to have moderate amounts of eye-candy on your search page, as it will increase the perceived quality of the results.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2011/05/14/document-thumbnails-and-powerpoint-preview-for-your-search-results-without-installing-fast-for-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The True Value of Enterprise Search Technology</title>
		<link>http://blog.comperiosearch.com/blog/2011/05/11/the-true-value-of-enterprise-search-technology/</link>
		<comments>http://blog.comperiosearch.com/blog/2011/05/11/the-true-value-of-enterprise-search-technology/#comments</comments>
		<pubDate>Wed, 11 May 2011 09:30:00 +0000</pubDate>
		<dc:creator><![CDATA[Vegard Sandvold]]></dc:creator>
				<category><![CDATA[User Experience]]></category>
		<category><![CDATA[business goals]]></category>
		<category><![CDATA[enterprise search]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[fs4sp]]></category>
		<category><![CDATA[ucd]]></category>
		<category><![CDATA[user needs]]></category>

		<guid isPermaLink="false">http://nuggets.comperiosearch.com/?p=449</guid>
		<description><![CDATA[Technology has no inherent business value. Technology doesn&#8217;t provide improved findabiliy, decision-making or knowledge management by itself. Technology just provides features that help users perform tasks, thereby reaching their goals. Only when user goals and business goals align, can you hope to create business value. Without people, there is no purpose &#8211; and without purpose, [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_452" style="width: 586px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2011/05/3332644561_c9d5041d02_z.jpg"><img class="size-full wp-image-452 " title="3332644561_c9d5041d02_z" src="http://blog.comperiosearch.com/wp-content/uploads/2011/05/3332644561_c9d5041d02_z.jpg" alt="" width="576" height="383" /></a><p class="wp-caption-text">flickr.com/theredproject</p></div>
<p><strong>Technology has no inherent business value.</strong> Technology doesn&#8217;t provide improved findabiliy, decision-making or knowledge management by itself. Technology just provides features that help users perform tasks, thereby reaching their goals. Only when user goals and business goals align, can you hope to create business value. Without people, there is no purpose &#8211; and without purpose, there is no value.</p>
<p>Enterprise search technology is no different from the rest in this respect. In fact, <strong>I know only 3 good reasons for investing in search technology</strong>.</p>
<p><span id="more-449"></span></p>
<p>Spending time and money on an enterprise search platform like FAST Search For SharePoint (FS4SP) may be a good idea if you believe the success of your business depends on:</p>
<ol>
<li>Consolidation of information from different data sources and formats.</li>
<li>Content refinement and entity extraction.</li>
<li>Linguistic processing and advanced querying capabilities.</li>
</ol>
<p>There is of course more to search than this, but these features are in my opinion the hallmarks of FS4SP and the old FAST ESP &#8211; what enterprise search does better, faster and with higher tractability than any other available technology. Search is by no means the only way to access information, and similar technologies (like <a href="http://en.wikipedia.org/wiki/Data_warehouse">data warehouse</a>, <a href="http://en.wikipedia.org/wiki/Extract,_transform,_load">ETL</a> and <a href="http://en.wikipedia.org/wiki/Topic_Maps">topic maps</a>) will let you do similar things, each having their own particular strengths and weaknesses.</p>
<p>The true value of enterprise search technology is not bound to fair promises of improved efficiency and profitability, but to the marvels it can do in the hands of brilliant engineers &#8211; without requiring any prior knowledge of the context of use. Business value is only attainable when technological capabilities form a higher unity with user needs and business goals through cross-diciplinary user-centered design.</p>
<p>The success of your business may depend on improved findability, decision-making and knowledge management, and that is<strong> the true value of designing the user experience of search</strong>.</p>
<p><em>Note: this post is cross-posted at <a href="http://www.thingsontop.com/true-enterprise-search-technology-1171.html">Things On Top</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2011/05/11/the-true-value-of-enterprise-search-technology/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Working with crawled and managed properties via code</title>
		<link>http://blog.comperiosearch.com/blog/2011/05/04/working-with-crawled-and-managed-properties-via-code/</link>
		<comments>http://blog.comperiosearch.com/blog/2011/05/04/working-with-crawled-and-managed-properties-via-code/#comments</comments>
		<pubDate>Wed, 04 May 2011 20:52:13 +0000</pubDate>
		<dc:creator><![CDATA[Mikael Svenson]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[fs4sp]]></category>
		<category><![CDATA[sp2010]]></category>

		<guid isPermaLink="false">http://nuggets.comperiosearch.com/2011/05/working-with-crawled-and-managed-properties-via-code/</guid>
		<description><![CDATA[I was teaching a FAST for SharePoint Workshop today and we were doing labs on creating and mapping crawled properties to managed properties with the FAST Administration UI and via PowerShell. But one student wanted to know how to do this in code, hence this blog post. Instead of having a deployment script creating your [...]]]></description>
				<content:encoded><![CDATA[<p>I was teaching a FAST for SharePoint Workshop today and we were doing labs on creating and mapping crawled properties to managed properties with the FAST Administration UI and via PowerShell. But one student wanted to know how to do this in code, hence this blog post.</p>
<p>Instead of having a deployment script creating your properties, you could have an event receiver which creates your mappings once a site or list is provisioned. Or when some other action is going on.</p>
<p>So how do you go about doing this?</p>
<p>Well, first off Crawled and Managed Properties for FAST are a part of the index schema and is accessible via the following two namespaces:</p>
<p><strong><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.search.extended.administration.aspx">Microsoft.SharePoint.Search.Extended.Administration</a></strong> <strong><a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.search.extended.administration.schema.aspx">Microsoft.SharePoint.Search.Extended.Administration.Schema</a></strong></p>
<p>which are the namespaces used for working with the FAST components.</p>
<p>Below is a quick example showing how this can be done in code, with comments along the way to guide the process. It’s all pretty straight forward.</p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">const</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> </span><span><span style="color: #0000ff;">string</span></span><span style="color: #000000;"> propertyName = </span><span><span style="color: #a31515;">&#8220;productname&#8221;</span></span><span style="color: #000000;">;</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Get a reference to the Index Schema via the SchemaContext class</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">SchemaContext</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> schemaContext = </span><span><span style="color: #0000ff;">new</span></span><span style="color: #000000;"> </span><span><span style="color: #2b91af;">SchemaContext</span></span><span style="color: #000000;">();</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">Schema</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> schema = schemaContext.Schema;</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Assign a guid to the custom Crawled Propery Category</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">Guid</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> myGuid = </span><span><span style="color: #0000ff;">new</span></span><span style="color: #000000;"> </span><span><span style="color: #2b91af;">Guid</span></span><span style="color: #000000;">(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">Category</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> catGroup;</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Create if it does not exist</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">if</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> (!schema.AllCategories.Contains(myGuid))</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">{</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">catGroup = schema.AllCategories.Create(</span></span><span style="font-size: 9.5pt;"><span><span style="color: #a31515;">&#8220;My Crawled Properties&#8221;</span></span><span style="color: #000000;">, myGuid);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">}</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #0000ff;">else</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">{</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">catGroup = schema.AllCategories[myGuid];</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">}</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Create a new crawled property if it doesn&#8217;t exist</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">CrawledProperty</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> cp = catGroup.GetAllCrawledProperties().Where(</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">c =&gt; c.Name == propertyName &amp;&amp; c.VariantType == 31 &amp;&amp; c.Propset == myGuid).FirstOrDefault();</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">if</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> (cp == </span><span><span style="color: #0000ff;">null</span></span><span style="color: #000000;">) cp = catGroup.CreateCrawledProperty(propertyName, myGuid, 31);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Create a new managed property if it doesn&#8217;t exist</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">ManagedProperty</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> mp;</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">if</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> (!schema.AllManagedProperties.Contains(propertyName))</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">{</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">mp = schema.AllManagedProperties.Create(propertyName, </span></span><span style="font-size: 9.5pt;"><span><span style="color: #a31515;">&#8220;&#8221;</span></span><span style="color: #000000;">, </span><span><span style="color: #2b91af;">ManagedType</span></span><span style="color: #000000;">.Text);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">}</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #0000ff;">else</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">{</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">mp = schema.AllManagedProperties[propertyName];</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">}</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Create a new crawled to managed property mapping if it doesn&#8217;t exit</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">CrawledPropertyMapping</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> mapping = mp.GetCrawledPropertyMappings();</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">if</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> (!mapping.Contains(cp))</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">{</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">mapping.Add(cp);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">mp.SetCrawledPropertyMappings(mapping);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">}</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Get a reference to the default full text index (first one)</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">FullTextIndex</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> fti = schema.AllFullTextIndecies.First();</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;"> </span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Get the full text index mapping from the Managed Property</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">FullTextIndexMappingCollection</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> fullTextIndexMappingCollection = mp.GetFullTextIndexMappings();</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">FullTextIndexMapping</span></span></span><span><span style="font-size: 9.5pt; color: #000000;"> indexMapping =</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">fullTextIndexMappingCollection.Where(ftpMap =&gt; ftpMap.FullTextIndex.Name == fti.Name).FirstOrDefault();</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #008000;">// Set a mapping to importance level 6, if it&#8217;s not already set to something else</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span style="font-family: Consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">if</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> (indexMapping == </span><span><span style="color: #0000ff;">null</span></span><span style="color: #000000;"> || !fullTextIndexMappingCollection.Contains(indexMapping))</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">{</span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;"> </span></span><span style="font-size: 9.5pt;">fullTextIndexMappingCollection.Create(fti, 6);</span></span></span></span></p>
<p class="MsoNormal" style="line-height: normal; margin: 0cm 0cm 0pt; mso-layout-grid-align: none;"><span><span style="font-family: Consolas;"><span style="font-size: 9.5pt; color: #000000;">}</span></span></span></p>
<p class="MsoNormal" style="line-height: 13pt; margin: 0cm 0cm 10pt;"><span style="font-family: Calibri;"><span style="font-size: 11pt; color: #000000;"> </span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2011/05/04/working-with-crawled-and-managed-properties-via-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Query Suggestions in FAST Search for SharePoint 2010 (FS4SP)</title>
		<link>http://blog.comperiosearch.com/blog/2011/05/03/query-suggestions-fast-search-4-sharepoint-2010-fs4sp/</link>
		<comments>http://blog.comperiosearch.com/blog/2011/05/03/query-suggestions-fast-search-4-sharepoint-2010-fs4sp/#comments</comments>
		<pubDate>Tue, 03 May 2011 09:10:58 +0000</pubDate>
		<dc:creator><![CDATA[Trond Øivind Eriksen]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[fs4sp]]></category>
		<category><![CDATA[query completion]]></category>
		<category><![CDATA[query suggestions]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[sharepoint]]></category>
		<category><![CDATA[sp2010]]></category>

		<guid isPermaLink="false">http://nuggets.comperiosearch.com/?p=409</guid>
		<description><![CDATA[Adding query suggestions to your search solution is a feature that can contribute to a better search experience for end-users. First of all, it makes us save time as we don&#8217;t have to type in the entire query. Secondly, it can help the user avoid potential spelling errors,  which in turn can reduce the quality of the [...]]]></description>
				<content:encoded><![CDATA[<p>Adding query suggestions to your search solution is a feature that can contribute to a better search experience for end-users. First of all, <em>it makes us save time</em> as we don&#8217;t have to type in the entire query. Secondly, it can help the user <em>avoid potential spelling errors</em>,  which in turn can reduce the quality of the results, and avoid that the user has to spend more time finding the information he/she is looking for. Also,  it can aid the user to do the first search more specific, by <em>adding information that may be pertinent to the search</em>.</p>
<p>With FS4SP,  these query suggestions are automatically created over a period of time based on how often the users search for a specific query within a certain timeframe. Sometimes, it can however make sense to modify the query suggestions manually &#8211; and to help us do that, we can always lean on PowerShell.</p>
<p>The script I have implemented, has the following parameters:</p><pre class="crayon-plain-tag">.\QuerySuggestions.ps1 -file [fileName] -action [add|delete] -queryssa [querySSAName]</pre><p>where <em>file</em> is the file with the query suggestion phrases (one per line), <em>action</em> decides if the query suggestions should be added or deleted, <em>queryssa</em> is the name of the Query SSA. And now for the actual code.</p><pre class="crayon-plain-tag">#Get input
param
(
    [string]$file,
    [string]$action,
    [string]$queryssa
)

function LoadQueryCompletion()
{
    # Read input file with stuff that you should add to the Query suggestion list
    if (test-path $file)
    {
        log VERBOSE &quot;Reading file: $file&quot;
	$input = Get-Content $file
    }
    else
    {
        log ERROR &quot;File noe found. Exiting script.&quot;
        exit 1
    }
    # Get SSA search application
    $searchapp = Get-SPEnterpriseSearchServiceApplication -Identity $queryssa

    # Populating a dictionary with the query suggestions that have already been added before
    $query_suggestions = Get-SPEnterpriseSearchLanguageResourcePhrase -SearchApplication $searchapp -Language En-Us -Type QuerySuggestionAlwaysSuggest
    $already_dict = @{}
    foreach ($term in $query_suggestions)
    {
        if (!$term){ continue }
        $already_dict.Add($term.Phrase,$term.Phrase)
    }

    if ($action -eq &quot;add&quot;)
	{
	    foreach ($entry in $input) {
	        if ($already_dict.ContainsKey($entry))
	        {
	            log WARNING &quot;Key already added: $entry&quot;
	        }
	        else
	        {

			try {
				log VERBOSE &quot;Adding entry ($entry) with language En-US&quot;
			    	$nooutput = new-spenterprisesearchlanguageresourcephrase -SearchApplication $searchapp -Language En-Us -Type QuerySuggestionAlwaysSuggest -Name $entry
				$already_dict.Add($entry,$entry)
			}catch {
				log ERROR &quot;Could not add entry ($entry). Exiting script.&quot;
				exit 1
			}
	        }
	    }
	}
	elseif ($action -eq &quot;delete&quot;)
	{
		foreach ($entry in $input) {
			try {
				if ($already_dict.ContainsKey($entry)) {
					log VERBOSE &quot;Removing entry ($entry) with language En-US&quot;
			    	        $nooutput = remove-spenterprisesearchlanguageresourcephrase -SearchApplication $searchapp -Language En-Us -Type QuerySuggestionAlwaysSuggest -Identity $entry -Confirm:$false
					$already_dict.Remove($entry)
				}else{
					log WARNING &quot;Entry ($entry) has not been added as a query suggestion&quot;
				}
			}catch {
				log ERROR &quot;Could not remove entry ($entry).&quot;
			}
	    }
	}
	else
	{
		log ERROR &quot;-action parameter contains an invalid value. Exiting script.&quot;
	}

    #Run timerjob manually to upload entries from DB
    Start-SPTimerJob -Identity &quot;prepare query suggestions&quot;

    log VERBOSE &quot;Finished loading query completion phrases.&quot;
}

#Main
$spInstalled = Get-PSSnapin | Select-String Sharepoint
if (!$spInstalled)
{
    Add-PSSnapin Microsoft.Sharepoint.PowerShell
}
LoadQueryCompletion</pre><p>If you want to include the logging output , add this to the top of the PowerShell script.</p><pre class="crayon-plain-tag"># Log level to color mapping
$lc = @{
	VERBOSE=&quot;green&quot;;
	WARNING=&quot;yellow&quot;;
	ERROR=&quot;red&quot;;
	MESSAGE=&quot;blue&quot;;
}
function log([string] $level, [string] $message) {
	$date = get-date -uformat &quot;%G-%m-%d %T&quot;
	write-host &quot;[$date] &quot; -nonewline
	write-host -foregroundcolor $lc[$level] $level.padright(7) -nonewline
	write-host &quot; $message&quot;
}</pre><p>If you&#8217;re really picky (like me), you should also consider having some kind of validation on the input parameters. For instance verifying that the file exists, that the action parameter contains a valid value, and that the Query SSA exists. You can check the last-mentioned by adding the following lines of code to the script.</p><pre class="crayon-plain-tag">$ssaExists = Get-SPEnterpriseSearchServiceApplication | Select-String $queryssa
if ($ssaExists -eq $null)
{
	log ERROR &quot;-queryssa is invalid. Search Service Application does not exist. Exiting script.&quot;
	$queryssas = Get-SPEnterpriseSearchServiceApplication | Where-Object {$_.DefaultSearchProvider -eq &quot;FASTSearch&quot;}
	foreach ($queryssa in $queryssas)
        {
		if ($queryssa)
    	    	{
    			$name = $queryssa.Name
    			log VERBOSE &quot;Found the following Query SSA: $name&quot;
    	    	}
        }
}</pre><p>After doing that, you should be ready to run the script on the SharePoint Admin server.</p>
<p>Afterwards, go to your FAST Search Center, and start typing one of the terms you have added. The result can look something like in the screenshot below.</p>
<p><img class="alignnone size-full wp-image-410" src="http://blog.comperiosearch.com/wp-content/uploads/2011/05/QuerySuggestions.png" alt="" width="428" height="246" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2011/05/03/query-suggestions-fast-search-4-sharepoint-2010-fs4sp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
