<?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; Technology</title>
	<atom:link href="http://blog.comperiosearch.com/blog/category/tech/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>Sitevision – förbättra söket med Nutch</title>
		<link>http://blog.comperiosearch.com/blog/2016/06/08/sitevision-forbattra-soket-med-nutch/</link>
		<comments>http://blog.comperiosearch.com/blog/2016/06/08/sitevision-forbattra-soket-med-nutch/#comments</comments>
		<pubDate>Wed, 08 Jun 2016 14:20:07 +0000</pubDate>
		<dc:creator><![CDATA[Jack Thorén]]></dc:creator>
				<category><![CDATA[Nutch]]></category>
		<category><![CDATA[Sitevision]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[CRM]]></category>
		<category><![CDATA[web crawler]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=4096</guid>
		<description><![CDATA[Ett av Sveriges mest populära CMS verktyg är Sitevision, som används kanske främst av stora statliga myndigheter och kommuner. Valet att använda sig av Sitevision hos dessa myndigheter och kommuner är nog att det är väldigt enkelt för redaktörer och sidansvariga att använda och att underhålla informationen på sina sidor. Detta i en miljö där [...]]]></description>
				<content:encoded><![CDATA[<p>Ett av Sveriges mest populära CMS verktyg är Sitevision, som används kanske främst av stora statliga myndigheter och kommuner. Valet att använda sig av Sitevision hos dessa myndigheter och kommuner är nog att det är väldigt enkelt för redaktörer och sidansvariga att använda och att underhålla informationen på sina sidor. Detta i en miljö där kanske den webbtekniska kunskapen inte är på samma nivå som hos ett större teknikföretag.</p>
<p>Men medans vi hyllar det enkla användargränssnittet så önskar vi att det gick att bygga bättre sökfunktionalitet. Visst kan du söka i en webbsajt, det går även att söka på andra webbsajter, om du har satt upp flera webbsajter inom samma system. Men om du vill söka i en webbsajt eller databas som finns någon annanstans då går det inte. Men detta är på väg att ändras. Sitevision introducerar snart webbkravlaren Nutch, en mycket avancerad webcrawler som bygger på Hadoop, som i sin tur är del av ett ramverk för att hantera mycket stora mängder data. Nutch tillsammans med Solr kommer att lyfta Sitevisions sök till nya höjder.</p>
<p><strong>Nedan är ett schema för hur en sajt-indexering skulle kunna se </strong><strong>ut:</strong></p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/06/Jack_blog011.png"><img class="alignnone  wp-image-4098" src="http://blog.comperiosearch.com/wp-content/uploads/2016/06/Jack_blog011.png" alt="Jack_blog01" width="605" height="287" /></a></p>
<p>1. ”Injector” tar alla webbadresser i nutch.txt filen och lägger till dem i ”CrawlDB&#8221;. Som är en central del av Nutch. CrawlDB innehåller information om alla kända webbadresser (hämta schema, hämta status, metadata, &#8230;).</p>
<p>2. Baserat på data från CrawlDB skapar ”Generator” en lista på vad som ska hämtas och placerar det i en nyskapad segment katalog.</p>
<p>3. Nästa steg, ”Fetcher” får de adresser som ska hämtas från listan och skriver det tillbaka till segment katalogen. Detta steg är vanligtvis den mest tidskrävande delen.</p>
<p>4. Nu kan ”Parser” behandla innehållet i varje webbsida och exempelvis utelämnar alla html-taggar. Om denna hämtning (crawl) är en uppdatering eller en utökning av en redan tidigare hämtning (t.ex. djup 3), skulle ”Updater” lägga till nya data till CrawlDB som ett nästa steg.</p>
<p>5. Före indexering måste alla länkar inverteras av ”Link Inverter”, som tar hänsyn till att inte antalet utgående länkar på en webbsida är av intresse, utan snarare antalet inkommande länkar. Detta är ganska likt hur Google Pagerank fungerar och är viktig för scoring funktion. De inverterade länkarna sparas i “Linkdb”.</p>
<p>6-7. Med hjälp av data från alla möjliga källor (CrawlDB, LinkDB och segment), skapar Indexer ett index och sparar det i Solr katalogen. För indexering, används det populära Lucene biblioteket. Nu kan användaren söka efter information om genomsökta webbsidor via Solr.</p>
<p><strong>Funktionalitet som följer med Nutch:</strong></p>
<ul>
<li>Indexering av externa källor</li>
<li>Automatisk kategorisering</li>
<li>Metadata</li>
<li>Textanalys</li>
<li>Utökad funktionalitet enkelt med plugins</li>
</ul>
<p><strong>Nyttiga länkar:</strong></p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Apache_Nutch">https://en.wikipedia.org/wiki/Apache_Nutch</a></li>
<li><a href="http://wiki.apache.org/nutch/">http://wiki.apache.org/nutch/</a></li>
<li><a href="http://nutch.apache.org/">http://nutch.apache.org/</a></li>
<li><a href="http://www.sitevision.se/vara-produkter/sitevision.html">http://www.sitevision.se/vara-produkter/sitevision.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2016/06/08/sitevision-forbattra-soket-med-nutch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Experimenting with Open Source Web Crawlers</title>
		<link>http://blog.comperiosearch.com/blog/2016/04/29/experimenting-with-open-source-web-crawlers/</link>
		<comments>http://blog.comperiosearch.com/blog/2016/04/29/experimenting-with-open-source-web-crawlers/#comments</comments>
		<pubDate>Fri, 29 Apr 2016 11:03:42 +0000</pubDate>
		<dc:creator><![CDATA[Mridu Agarwal]]></dc:creator>
				<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[OpenWebSpider]]></category>
		<category><![CDATA[Scrapy]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[Web Crawling]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=4080</guid>
		<description><![CDATA[Whether you want to do market research or gather financial risk information or just get news about your favorite footballer from various news site,  web scraping has many uses. In my quest to learn know more about web crawling and scraping , I decided to test couple of Open Source Web Crawlers which were not [...]]]></description>
				<content:encoded><![CDATA[<p lang="en-US">Whether you want to do market research or gather financial risk information or just get news about your favorite footballer from various news site,  web scraping has many uses.</p>
<p lang="en-US">In my quest to learn know more about web crawling and scraping , I decided to test couple of Open Source Web Crawlers which were not only easily available but quite powerful as well. In this article I am mostly going to cover their basic features and how easy they are to start with.</p>
<p lang="en-US">If you are like one of those persons who likes to quickly get started while learning something, I would suggest that you try <a href="http://www.openwebspider.org/">OpenWebSpider</a> first.</p>
<p lang="en-US">It is a simple web browser based open source crawler and search engine which is simple to install and use and is very good for those who are trying to get acquainted to web crawling . It stores webpages in MySql or MongoDb. I used MySql for my testing purpose. You can follow the steps <a href="http://www.openwebspider.org/documentation/openwebspider-js/">here</a> to install it. It&#8217;s pretty simple and basic.</p>
<p lang="en-US">So, once you have installed everything , you just need to open a web-browser at <a href="http://127.0.0.1:9999/">http://127.0.0.1:9999/</a> and you are ready to crawl and search. Just check your database settings, type the Url of the site you want to crawl and within couple of minutes, you have all the data you need. You can even search it going to the search tab and typing in your query. Whoa! That was quick and compact and needless to say you don’t need any programming skills to crawl it.</p>
<p lang="en-US">If you are trying to create an off-line copy of your data or your very own mini Wikipedia, I think go for this as it’s the easiest way to do it.</p>
<p lang="en-US">Following are some screen shots:</p>
<p lang="en-US"><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/OS1.png"><img class="alignleft wp-image-4083 size-full" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/OS1.png" alt="OpenWebSpider" width="613" height="438" /></a></p>
<p lang="en-US"><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/OS2.png"><img class="alignleft wp-image-4086 size-full" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/OS2.png" alt="OpenSearchWeb" width="611" height="441" /></a></p>
<p lang="en-US" style="text-align: left"><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/OS3.png"><img class="alignleft size-full wp-image-4087" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/OS3.png" alt="OpenSearchWeb" width="611" height="441" /></a></p>
<p lang="en-US" style="text-align: left">You can also see the this Search engine demo <a href="http://lab.openwebspider.org/search_engine/">here</a>, before actually getting started.</p>
<p lang="en-US" style="text-align: left">Ok, after getting my hands on into web crawling, I was curious to do  more sophisticated stuff like extracting topics from a web site where I do not have any RSS feed or API. Extracting this structured data could be quite important to many business scenarios where you are trying to follow competitor&#8217;s product news or gather data for business intelligence. I decided to use <a href="http://scrapy.org/">Scrapy</a> for this experiment.</p>
<p lang="en-US" style="text-align: left">The good thing about Scrapy is that it is not only fast and simple, but very extensible as well. While installing it on my windows environment, I had few hiccups mainly because of the different compatible version of python but in the end, once you get it, it&#8217;s very simple(Isn&#8217;t that how you feel anyways , once things works ? Anyways, forget it! :D). Follow these links, if you are having trouble installing Scrapy like me:</p>
<p lang="en-US" style="text-align: left"><a href="https://github.com/scrapy/scrapy/wiki/How-to-Install-Scrapy-0.14-in-a-64-bit-Windows-7-Environment">https://github.com/scrapy/scrapy/wiki/How-to-Install-Scrapy-0.14-in-a-64-bit-Windows-7-Environment</a></p>
<p lang="en-US" style="text-align: left"><a href="http://doc.scrapy.org/en/latest/intro/install.html#intro-install">http://doc.scrapy.org/en/latest/intro/install.html#intro-install</a></p>
<p lang="en-US" style="text-align: left">After installing, you need to create a Scrapy project. Since we are doing more customized stuff than just crawling the entire website, this requires more effort and knowledge of programming skills and sometime browser tools to understand the HTML DOM. You can follow <a href="http://doc.scrapy.org/en/latest/intro/overview.html">this</a> link to get started with you first Scrapy project .Once you have crawled the data that you need, it would be interesting to feed this data into a search engine. I have also been looking for open source web crawlers for Elastic Search and this looked like the perfect opportunity. Scrapy provides integration with Elastic Search out of the box , which is awesome. You just need to install the Elastic Search module for Scrapy(of course Elastic Search should be running somewhere) and configure the Item Pipeline for Scrapy. Follow <a href="http://blog.florian-hopf.de/2014/07/scrapy-and-elasticsearch.html">this</a> link for the step by step guide. Once done, you have the fully integrated crawler and search system!</p>
<p lang="en-US" style="text-align: left">I crawled <a href="http://primehealthchannel.com">http://primehealthchannel.com</a> and created an index named &#8220;healthitems&#8221; in Scrapy.</p>
<p lang="en-US" style="text-align: left">To search the elastic search index, I am using Chrome extension <span style="font-weight: bold">Sense</span> to send queries to Elastic Search, and this is how it looks</p>
<p lang="en-US" style="text-align: left">GET /scrapy/healthitems/_search</p>
<p style="text-align: left"><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/ES1.png"><img class="alignleft wp-image-4082 size-large" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/ES1-1024x597.png" alt="Elastic Search" width="1024" height="597" /></a></p>
<p lang="en-US" style="text-align: left">I hope you had fun reading this and now wants to try some of your own cool ideas . Do let us know how you used it and which crawler you like the most!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2016/04/29/experimenting-with-open-source-web-crawlers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extern data sökbart i SharePoint Online</title>
		<link>http://blog.comperiosearch.com/blog/2016/04/26/extern-data-sokbart-i-sharepoint-online/</link>
		<comments>http://blog.comperiosearch.com/blog/2016/04/26/extern-data-sokbart-i-sharepoint-online/#comments</comments>
		<pubDate>Tue, 26 Apr 2016 14:33:45 +0000</pubDate>
		<dc:creator><![CDATA[Joel Lindefors]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Extern data]]></category>
		<category><![CDATA[External data]]></category>
		<category><![CDATA[OData]]></category>
		<category><![CDATA[OData Service]]></category>
		<category><![CDATA[SharePoint Online]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=4063</guid>
		<description><![CDATA[I min förra bloggpost  om extern data i SharePoint Online presenterade jag ett exempel på hur vi utan att behöva koda kan arbeta med extern data i SharePoint Online. Nackdelen med den lösningen var att datat i det fallet inte blev sökbart i och med att vi använde oss av en extern innehållstyp som var [...]]]></description>
				<content:encoded><![CDATA[<p><strong>I min förra <a href="http://blog.comperiosearch.com/blog/2016/04/26/extern-data-i-sharepoint-online/" target="_blank">bloggpost</a>  om extern data i SharePoint Online presenterade jag ett exempel på hur vi utan att behöva koda kan arbeta med extern data i SharePoint Online. Nackdelen med den lösningen var att datat i det fallet inte blev sökbart i och med att vi använde oss av en extern innehållstyp som var kopplad till en extern lista. I den här bloggposten ska jag inte bara presentera ett exempel på hur vi kan göra externt data möjligt att arbeta med utan också sökbart i SharePoint Online med hälp av en OData Service, en vanlig SharePoint lista och Javascript Object Model. Vad vi kan göra med datat i SharePoint Online är helt beroende på vilka CRUD operationer vi väljer att lägga till i den javascript kod vi skriver. Väljer vi att lägga till alla operationer kommer vi också kunna läsa, lägga till, uppdatera och ta bort data ur databasen.</strong></p>
<p><strong>I mitt exempel här nedan har jag använt mig av en redan befintlig och publik OData service. Om det inte redan finns någon sådan som ni kan använda er av måste ni skapa upp en sådan först. Mer info kring hur man skapar upp <a href="https://msdn.microsoft.com/en-us/data/gg601462.aspx" target="_blank">OData service</a> kan ni få om ni klickar på länken. Jag har också redan skapat upp en vanlig ”Custom List” och gett den namnet ”List 1” i min SharePoint Online site. Jag har även skapat upp en kolumn som heter ”Description” utöver ”Title” kolumnen som redan finns. Om du har ett scenario där den externa databasen även kan uppdateras från annat ställe än din SharePoint Online lista behöver du också skapa upp något som uppdaterar din SharePoint lista exempelvis ett <a href="https://blogs.msdn.microsoft.com/richard_dizeregas_blog/2014/04/07/sharepoint-timer-jobs-running-as-windows-azure-web-jobs/." target="_blank">Windows Azure Web Job</a>.</strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Välj ”File”, ”New”, ”Project” i Visual Studio och välj därefter ”SharePoint Add-In”. Ge projektet ett namn och välj SharePoint-hosted.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddSharePointAddIn.png"><img class="size-full wp-image-1453 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddSharePointAddIn.png" alt="AddSharePointAddIn" width="605" height="440" /></a></p>
<p>I Visual Studio öppnar vi nu upp foldern Scripts och klickar på App.js</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AppJs.png"><img class="wp-image-1458 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AppJs.png" alt="AppJs" width="334" height="497" /></a></p>
<p>&nbsp;</p>
<p>Lägg in nedanstående kodsnuttar i App.js. Notera att i exemplet nedan har vi bara valt en Read operation, så lägger man till, editerar eller tar bort objekt så kommer inget att hända i databasen.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/JavaScript.png"><img class="wp-image-1459 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/JavaScript.png" alt="JavaScript" width="653" height="401" /></a></p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/JavaScript01.png"><img class="wp-image-1460 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/JavaScript01.png" alt="JavaScript01" width="498" height="445" /></a></p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/Javascript03.png"><img class="alignnone size-medium wp-image-4064" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/Javascript03-300x129.png" alt="Javascript03" width="300" height="129" /></a></p>
<p>Nu behöver vi ge appen behörighet till listan. Klicka på AppManifest i Solution Explorer fönstret i Visual Studio och välj ”Permissions”. I exemplet nedan har jag gett appen full behörighet till hela site collection.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/AppManifest.png"><img class="alignnone size-medium wp-image-4065" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/AppManifest-300x257.png" alt="AppManifest" width="300" height="257" /></a></p>
<p>&nbsp;</p>
<p>Klicka på fliken för ”Remote Endpoint” och lägg till hosturlen till OData servicen.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/AppManifest02.png"><img class="alignnone size-full wp-image-4067" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/AppManifest02.png" alt="AppManifest02" width="605" height="490" /></a></p>
<p>&nbsp;</p>
<p>Nu deployar vi vår lösning och när deployen är färdig är vi redo att gå in i vår SharePoint Online lista och se att alla objekt har kommit in</p>
<p>. <a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/Solution2Result.png"><img class="alignnone  wp-image-4068" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/Solution2Result.png" alt="Solution2Result" width="524" height="404" /><br />
</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Vi kan nu också gå till vår sök och söka efter ett av våra objekt. Jag valde att söka på Condiments och nedan är resultatet.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2016/04/SearchResult.png"><img class="alignnone  wp-image-4076" src="http://blog.comperiosearch.com/wp-content/uploads/2016/04/SearchResult.png" alt="SearchResult" width="578" height="381" /></a></p>
<p>&nbsp;</p>
<p>Email: joel.lindefors@comperiosearch.com</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2016/04/26/extern-data-sokbart-i-sharepoint-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extern data i SharePoint Online</title>
		<link>http://blog.comperiosearch.com/blog/2016/04/26/extern-data-i-sharepoint-online/</link>
		<comments>http://blog.comperiosearch.com/blog/2016/04/26/extern-data-i-sharepoint-online/#comments</comments>
		<pubDate>Tue, 26 Apr 2016 12:20:49 +0000</pubDate>
		<dc:creator><![CDATA[Joel Lindefors]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Azure SQL Server]]></category>
		<category><![CDATA[Business Connectivity Service]]></category>
		<category><![CDATA[Extern data]]></category>
		<category><![CDATA[Extern innehållstyp]]></category>
		<category><![CDATA[Extern lista]]></category>
		<category><![CDATA[External content type]]></category>
		<category><![CDATA[External list]]></category>
		<category><![CDATA[SharePoint Online]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=4053</guid>
		<description><![CDATA[I den här bloggposten kommer vi presentera ett exempel på hur man kan göra data från en Azure SQL Server databas tillgängligt att arbeta med i SharePoint Online genom att skapa upp en Business Connectivity Service, extern innehållstyp och en extern lista. Fördelen med exemplet är att man med endast konfigurering kan koppla en databas från Azure till SharePoint Online [...]]]></description>
				<content:encoded><![CDATA[<p><strong style="font-style: inherit">I den här bloggposten kommer vi presentera ett exempel på hur man kan göra data från en Azure SQL Server databas tillgängligt att arbeta med i SharePoint Online genom att skapa upp en Business Connectivity Service, extern innehållstyp och en extern lista. Fördelen med exemplet är att man med endast konfigurering kan koppla en databas från Azure till SharePoint Online och genom SharePoint Online kan uppdatera databasen (beroende på vilka operationer vi väljer att lägga till i externa innehållstypen). Det här är en av få vägar att på ett enkelt sätt kunna få in externt data utan att på egen hand behöva genomföra någon kodning. Nackdelen med exemplet är att den externa datan inte blir sökbar i SharePoint Online. Nedanstående exempel går att finna på msdn med skillnaden att de där också skapar upp en databas i Azure SQL Server och att jag inte fick det att fungera förrän jag lagt till en brandväggsregel i Azure SQL Server databasen.</strong></p>
<p>&nbsp;</p>
<p>Skapa Business Connectivity Service genom att i SharePoint Admin Center välja bcs och sedan ”Manage connections to online services”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddBcs2.png"><img class="wp-image-1391 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddBcs2-1024x548.png" alt="AddBcs" width="746" height="399" /></a></p>
<p>&nbsp;</p>
<p>Klicka på “Add”. Ange ett namn för kopplingen och service adressen, vilket är adressen till SQLServern i Azure.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddBcs011.png"><img class="wp-image-1392 alignleft" src="http://www.comperio.no/wp-content/uploads/2016/04/AddBcs011.png" alt="AddBcs01" width="493" height="318" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Skapa Secure Store Service ID genom att klicka på Secure Store i SharePoint Admin Center och sedan välja ”New”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID.png"><img class="alignnone  wp-image-1395" src="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID.png" alt="AddSecureStoreID" width="425" height="414" /></a></p>
<p>&nbsp;</p>
<p>Fyll i “Application ID”, “Display Name”, “Contact E-Mail”. Notera att ”Application ID” inte kan ändras när det väl har skapats.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID01.png"><img class="alignnone  wp-image-1397" src="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID01.png" alt="AddSecureStoreID01" width="405" height="230" /></a></p>
<p>&nbsp;</p>
<p>Lägg till de fält som behöver användas för att accessa data i ”Target Application”. Som default är fälten ”Windows User Name” och ”Windows Password” tillagt med fälttyperna ”User Name” och ”Password” kopplade till sig och där ”Password” är maskerat. Man kan välja att lägga till andra fält också om man behöver.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID02.png"><img class="alignnone  wp-image-1400" src="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID02.png" alt="AddSecureStoreID02" width="676" height="126" /></a></p>
<p>&nbsp;</p>
<p>Lägg till ”administrators” och ”members” av ”Target Application”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID03.png"><img class="alignnone  wp-image-1402" src="http://www.comperio.no/wp-content/uploads/2016/04/AddSecureStoreID03.png" alt="AddSecureStoreID03" width="522" height="159" /></a></p>
<p>&nbsp;</p>
<p>Klicka ok. Du kommer nu tillbaka till ”Secure Store Service” sidan.</p>
<p>Nu när vi har skapat upp ”Target Application” behöver vi sätta ”credentials” som Secure Store använder för att hämta data från Azure SQL databasen. Välj den ”application” som du nyss skapat och klicka ”Set Credentials”. Använd samma användarnamn och lösenord som det användarnamn och lösenord som användes när din Azure SQL Database skapades upp.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/SetCredSecureStoreApp1.png"><img class="wp-image-1407 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/SetCredSecureStoreApp1.png" alt="SetCredSecureStoreApp" width="488" height="365" /></a></p>
<p>&nbsp;</p>
<p>Nu behöver vi ändra vilka &#8220;credentials&#8221; som ska användas för vår bcs. Vi angav tidigare ”User´s Identity”. Nu ska vi ändra det till ”Credentials stored in SharePoint”. Klicka på bcs i SharePoint Admin och välj ”Manage Connections to online servers” och välj det namn som du angav för din bcs koppling. Klicka på ”Properties” i menyn.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/BcsProp.png"><img class="size-full wp-image-1409 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/BcsProp.png" alt="BcsProp" width="247" height="180" /></a></p>
<p>&nbsp;</p>
<p>Ändra till ”Use Credentials Stored in SharePoint”. Ange det ”Secure Store Application ID” som du angav när du skapade upp din ”Target Application” i Secure Store.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/BcsProp01.png"><img class="wp-image-1413 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/BcsProp01.png" alt="BcsProp01" width="476" height="348" /></a></p>
<p>&nbsp;</p>
<p>I SharePoint Admin klicka på bcs och sedan ”Manage BDC Models and External Content Types”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtCont.png"><img class="size-full wp-image-1415 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtCont.png" alt="AddExtCont" width="604" height="321" /></a></p>
<p>&nbsp;</p>
<p>Välj ”Set Metadata Store Permissions” och välj användare. Minst en användare måste ha full behörighet.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/BdcMetaDataStorPerm.png"><img class="wp-image-1416 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/BdcMetaDataStorPerm.png" alt="BdcMetaDataStorPerm" width="452" height="468" /></a></p>
<p>&nbsp;</p>
<p>Nu ska vi skapa upp vår externa innehållstyp i SharePoint Designer. Öppna upp SharePoint Designer och välj din SharePoint Online site. Klicka på ”External Content Types” i vänstermenyn och välj ”External Content Type” i menyn högst upp enligt bilden nedan.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner.png"><img class="size-full wp-image-1417 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner.png" alt="AddExtContSPDesigner" width="604" height="368" /></a></p>
<p>&nbsp;</p>
<p>Ge din innehållstyp ett namn och klicka sedan på ”Discover external datasources and define operations.”</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner01.png"><img class="size-full wp-image-1420 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner01.png" alt="AddExtContSPDesigner01" width="602" height="232" /></a></p>
<p>&nbsp;</p>
<p>Klicka på ”Add connection” knappen.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner02.png"><img class="size-full wp-image-1421 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner02.png" alt="AddExtContSPDesigner02" width="417" height="160" /></a></p>
<p>&nbsp;</p>
<p>Ange adressen till din Azure SQL Server databas och namnet på din Azure SQL databas. Välj ”Connect with Impersonated Custom Identity”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner03.png"><img class="size-full wp-image-1422 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner03.png" alt="AddExtContSPDesigner03" width="371" height="243" /></a></p>
<p>&nbsp;</p>
<p>När du klickar ok kommer du få upp en inloggningsruta. Där anger du det användarnamn och det lösenord som du angivit för att nå Azure SQL Databasen.</p>
<p>I ”Data Source Explorer” har vi nu fått upp vår databas. Öppna upp ”Tables” och högerklicka på den tabell som du vill göra CRUD operationer på. Välj vilken/vilka operationer du vill kunna göra mot tabellen.</p>
<p>&nbsp;</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner04.png"><img class="wp-image-1423 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner04.png" alt="AddExtContSPDesigner04" width="409" height="327" /></a></p>
<p>&nbsp;</p>
<p>I det här exemplet har jag valt att skapa upp alla operationer och när de är färdigskapade kommer vi få upp nedanstående fönster. Klicka ”Next”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner05.png"><img class="size-full wp-image-1425 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner05.png" alt="AddExtContSPDesigner05" width="604" height="350" /></a></p>
<p>&nbsp;</p>
<p>I ”Parameters Configuration” fönstret kan vi få upp felmeddelande och varningar. I nedanstående exempel har vi fått upp en varning. För att få bort den varningen behöver vi klicka i ”Show in Picker”. Klicka sedan ”Next”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner06.png"><img class="size-full wp-image-1426 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner06.png" alt="AddExtContSPDesigner06" width="604" height="452" /></a></p>
<p>&nbsp;</p>
<p>I fönstret som nu öppnats ska vi lägga till ett filter så vi klickar ”Add Filter Parameter”. Vi använder oss av CustomerID för att ange en begräsning av 2000 objekt. För att ange begränsningen klickar vi på ”Click to add” bredvid ”Filter”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner07.png"><img class="size-full wp-image-1427 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner07.png" alt="AddExtContSPDesigner07" width="604" height="452" /></a></p>
<p>&nbsp;</p>
<p>Vi sätter ”Filter Type” till ”Limit” och klickar ”OK”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner08.png"><img class="size-full wp-image-1428 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner08.png" alt="AddExtContSPDesigner08" width="444" height="339" /></a></p>
<p>&nbsp;</p>
<p>Nu sätter vi ”Default value” till 2000 och klickar sedan ”Finnish”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner09.png"><img class="size-full wp-image-1429 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner09.png" alt="AddExtContSPDesigner09" width="604" height="454" /></a></p>
<p>&nbsp;</p>
<p>Klicka på spara knappen för att spara din externa innehållstyp till din SharePoint Online site. Nu när vi går tillbaka till SharePoint Admin Center och väljer bcs och ”Manage BDC Models and External Content Types kommer vi se vår koppling där. Klicka på drop down menyn och välj ”Set Permissions”.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner10.png"><img class="size-full wp-image-1430 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtContSPDesigner10.png" alt="AddExtContSPDesigner10" width="604" height="135" /></a></p>
<p>&nbsp;</p>
<p>Sök efter ”All Users” och lägg till både ”All Users (Windows)” och ”All Users (Membership)”. Ge båda ”Execute” och ”Selectable in Clients” behörigheter.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/SetExtContPerm.png"><img class="wp-image-1431 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/SetExtContPerm.png" alt="SetExtContPerm" width="473" height="479" /></a></p>
<p>&nbsp;</p>
<p>Innan vi kan skapa upp vår externa lista i vår SharePoint Online site måste vi också skapa upp en brandväggsregel till vår databas i Azure, så att Azure accepterar SharePoint att nå vår databas. Vi behöver ange en Start IP och Slut IP. Eftersom IP-adresserna i SharePoint Online är dynamiska behöver vi ange nedanstående Start och Slut IP.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AzureFirewallRule1.png"><img class="size-full wp-image-1442 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AzureFirewallRule1.png" alt="AzureFirewallRule" width="605" height="395" /></a></p>
<p>&nbsp;</p>
<p>Nu kan vi gå till ”Site Contents” på vår SharePoint Online site och välja ”add an app”. Lägg till en extern lista och välj den externa innehållstyp som vi skapat upp.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/AddExtList.png"><img class="size-full wp-image-1440 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/AddExtList.png" alt="AddExtList" width="604" height="289" /></a></p>
<p>&nbsp;</p>
<p>Ge listan ett namn och klicka skapa. Du borde nu kunna se dina externa objekt och beroende vilka operationer du lagt till editera, ta bort och lägga till objekt i listan.</p>
<p><a style="color: #0069d6" href="http://www.comperio.no/wp-content/uploads/2016/04/Solution1Result.png"><img class="wp-image-1439 alignnone" src="http://www.comperio.no/wp-content/uploads/2016/04/Solution1Result-1024x500.png" alt="Solution1Result" width="999" height="487" /></a></p>
<p>&nbsp;</p>
<p>Email: joel.lindefors@comperiosearch.com</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2016/04/26/extern-data-i-sharepoint-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Content Enrichment Web Service SharePoint 2013 &#8211; Advantages and Challenges</title>
		<link>http://blog.comperiosearch.com/blog/2016/04/26/content-enrichment-web-service-sharepoint-2013/</link>
		<comments>http://blog.comperiosearch.com/blog/2016/04/26/content-enrichment-web-service-sharepoint-2013/#comments</comments>
		<pubDate>Tue, 26 Apr 2016 11:23:22 +0000</pubDate>
		<dc:creator><![CDATA[Mridu Agarwal]]></dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[CEWS]]></category>
		<category><![CDATA[Content Enrichment Web Service]]></category>
		<category><![CDATA[FAST Search for SharePoint]]></category>
		<category><![CDATA[SharePoint 2013 Search]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=4017</guid>
		<description><![CDATA[If you have worked with search solutions before, you will know that very often there is a need to process data before it can be displayed in search results. This processing might be required to address some of(but not limited to) these common issues: Missing metadata issues Inconsistent metadata issues Cleansing of content Integration of semantic [...]]]></description>
				<content:encoded><![CDATA[<p>If you have worked with search solutions before, you will know that very often there is a need to process data before it can be displayed in search results. This processing might be required to address some of(but not limited to) these common issues:</p>
<ul>
<li>Missing metadata issues</li>
<li>Inconsistent metadata issues</li>
<li>Cleansing of content</li>
<li>Integration of semantic layers/Automatic tagging</li>
<li>Integration with 3rd party service</li>
<li>Merging data from other sources</li>
</ul>
<p><strong>Content Enrichment Web Service</strong> in SharePoint 2013 is a SOAP-based service within the content processing component that can be used to achieve this. The figure below shows a part of the process that takes place in the content processing component of SharePoint search. <img src="https://i-msdn.sec.s-msft.com/dynimg/IC618173.gif" alt="Content enrichment within content processing" width="481" height="286" /></p>
<p>Content Enrichment Web Service SharePoint 2013 combines the goodness of both <strong>FAST for SharePoint Search</strong> and <strong>SharePoint Search </strong> to offer a whole new set of possibilities and has its own challenges. To see an implementation example, check the <a href="https://msdn.microsoft.com/en-us/library/office/jj163982.aspx">MSDN link</a> which pretty much sums up the basic steps. In this post we are going to look at some of the advantages and challenges of CEWS coming from a FAST 2010 background:</p>
<p>1.<strong> CEWS is a service and you DON&#8217;T have to deploy it in your SharePoint environment</strong>: Perhaps this is the biggest architectural change  from the content processing perspective. What this means is that your code no longer runs in a sandbox environment within <strong>SharePoint Server</strong>. The webservice can be hosted anywhere outside your SharePoint server thus reducing deployment headaches and huge number of approvals required to deploy the executable files. I can see operations/infrastructure team/administrators smiling.</p>
<p>2.<strong>The web service processes and returns managed properties, not crawled properties: </strong>Managed properties correspond to what actually gets indexed and displayed in search results. So, this reduces some of the confusion as why I cant see the updated results( perhaps you had forgotten to map your crawled property to a managed property and wait you will have to index it AGAIN!). Nightmare!</p>
<p>3. <strong>You can define a trigger to limit the set of items that are processed by the web service: </strong>In FAST 2010, each item had to pass through the pipeline whether you wanted to process it or not. This check had to be done in the code. Trigger in 2013 will allow us to define this check outside the code so that only for selected content, web service is called. This will optimize the overall performance and improve crawling time, if you only want to process a subset of the content.</p>
<blockquote><p>So far, so good! But.. there are certain challenges we need to look at and see how we can overcome it. In fact, this is the most important part when you are architecting your CEWS solution:</p></blockquote>
<p>1. <strong>The content enrichment callout step can only be configured with a single web service endpoint :</strong> Now this sounds very limiting.  I have multiple search applications and earlier I maintained the logic in different solutions. Do I need to combine them all into a single service? What about the maintenance and change request? Well there are several possible technologies one could consider to solve this but what I did in my project was to create a WCF routing service and let the routing service handle my multiple web services based on filters. You could also use it to implement load-balancing and fault tolerance. Here in the following example, I have two content sources &#8220;xmlfile&#8221; and &#8220;EpiFileShare&#8221;. I want to have two different services &#8220;xmlsvc&#8221; and &#8220;episvc&#8221; to process these different sources. This is how I will configure the end points in my WCF Routing Service:   <a href="http://blog.comperiosearch.com/wp-content/uploads/2016/01/router.png"><img class="aligncenter  wp-image-4027" src="http://blog.comperiosearch.com/wp-content/uploads/2016/01/router-1024x278.png" alt="endpoints" width="708" height="192" /></a> 2.<strong> Only one condition can be configured for Trigger. Different search application will require different triggers: </strong>Now, this can again be solved by using WCF routers and filters and configuring separate endpoints for separate triggers. Here I am using default managed property &#8220;ContentSource&#8221; as a trigger/filter to determine my service endpoint. <a href="http://blog.comperiosearch.com/wp-content/uploads/2016/01/rouyer.png"><img class="aligncenter wp-image-4025 " src="http://blog.comperiosearch.com/wp-content/uploads/2016/01/rouyer-1024x286.png" alt="config file" width="737" height="206" /></a> To summarize, I have shown some of the advantages and challenges of the new CEWS architecture in SharePoint 2013 search and how you can overcome it. Hope that now you want  to try this soon and share your experience with us.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2016/04/26/content-enrichment-web-service-sharepoint-2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ELK stack deployment with Ansible</title>
		<link>http://blog.comperiosearch.com/blog/2015/11/26/elk-stack-deployment-with-ansible/</link>
		<comments>http://blog.comperiosearch.com/blog/2015/11/26/elk-stack-deployment-with-ansible/#comments</comments>
		<pubDate>Thu, 26 Nov 2015 09:59:38 +0000</pubDate>
		<dc:creator><![CDATA[Christoffer Vig]]></dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ansible]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[elk]]></category>
		<category><![CDATA[Kibana]]></category>
		<category><![CDATA[logstash]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=3999</guid>
		<description><![CDATA[As human beings, we like to believe that each and every one of us is a special individual, and not easily replaceable. That may be fine, but please, don’t fall into the habit of treating your computer the same way. Ansible is a free software platform for configuring and managing computers, and I’ve been using [...]]]></description>
				<content:encoded><![CDATA[<p><img class="alignright" src="http://www.ansible.com/hs-fs/hub/330046/file-767051897-png/Official_Logos/ansible_circleA_red.png?t=1448391213471" alt="" width="251" height="251" />As human beings, we like to believe that each and every one of us is a special individual, and not easily replaceable. That may be fine, but please, don’t fall into the habit of treating your computer the same way.</p>
<p><span id="more-3999"></span></p>
<p><a href="https://en.wikipedia.org/wiki/Ansible_(software)"><b>Ansible</b> </a>is a <a href="https://en.wikipedia.org/wiki/Free_software">free software</a> platform for configuring and managing computers, and I’ve been using it a lot lately to manage the ELK stack. Elasticsearch, Logstash and Kibana.</p>
<p>I can define a list of servers I want to manage in a YAML config file &#8211; the so called inventory:</p><pre class="crayon-plain-tag">[elasticearch-master]
es-master1.mydomain.com
es-master2.mydomain.com
es-master3.mydomain.com

[elasticsearch-data]
elk-data1.mydomain.com
elk-data2.mydomain.com
elk-data3.mydomain.com

[kibana]
kibana.mydomain.com</pre><p>And define the roles for the servers in another YAML config file &#8211; the so called playbook:</p><pre class="crayon-plain-tag">- hosts: elasticsearch-master
  roles:
    - ansible-elasticsearch

- hosts: elasticsearch-data
  roles:
    - ansible-elasticsearch

- hosts: logstash
  roles:
    - ansible-logstash

- hosts: kibana
  roles:
    - ansible-kibana</pre><p>&nbsp;</p>
<p>Each group of servers may have their own files containing configuration variables.</p><pre class="crayon-plain-tag">elasticsearch_version: 2.1.0
elasticsearch_node_master: false
elasticsearch_heap_size: 1000G</pre><p>&nbsp;</p>
<p>Ansible is used for configuring the ELK stack vagrant box at <a href="https://github.com/comperiosearch/vagrant-elk-box-ansible">https://github.com/comperiosearch/vagrant-elk-box-ansible</a>, which was recently upgraded with Elasticsearch 2.1, Kibana 4.3 and Logstash 2.1</p>
<p>The same set of Ansible roles can be applied when the configuration needs to move into production, by applying another set of variable files with modified host names, certificates and such. The possible ways to do this are several.</p>
<p><b>How does it work?</b></p>
<p>Ansible is agent-less. This means, you do not install anything (an agent) on the machines you control. Ansible needs only to be installed on the controlling machine (Linux/OSX) and  connects to the managed machines (some support for windows, even) using SSH. The only requirement on the managed machines is python.</p>
<p>Happy ansibling!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2015/11/26/elk-stack-deployment-with-ansible/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Analysing Solr logs with Logstash</title>
		<link>http://blog.comperiosearch.com/blog/2015/09/21/solr-logstash-analysis/</link>
		<comments>http://blog.comperiosearch.com/blog/2015/09/21/solr-logstash-analysis/#comments</comments>
		<pubDate>Sun, 20 Sep 2015 22:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Seb Muller]]></dc:creator>
				<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[analysis]]></category>
		<category><![CDATA[grok]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[logstash]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=3934</guid>
		<description><![CDATA[Analysing Solr logs with Logstash Although I usually write about and work with Apache Solr, I also use the ELK stack on a daily basis on a number of projects. If you&#8217;re not familiar with Solr, take a look at some of my previous posts. If you need some more background info on the ELK [...]]]></description>
				<content:encoded><![CDATA[<h1>Analysing Solr logs with Logstash</h1>
<p>Although I usually write about and work with <a href="http://lucene.apache.org/solr/">Apache Solr</a>, I also use the <a href="https://www.elastic.co/downloads">ELK stack</a> on a daily basis on a number of <a>projects.</a> If you&#8217;re not familiar with Solr, take a look at some of my <a href="http://blog.comperiosearch.com/blog/author/sebm/">previous posts</a>. If you need some more background info on the ELK stack, both <a href="http://blog.comperiosearch.com/blog/author/cvig/">Christoffer</a> and <a href="http://blog.comperiosearch.com/blog/author/alynum/">André</a> have written many great posts on various ELK subjects. The most common use for the stack is data analysis. In our case, Solr search log analysis.</p>
<p>As a little side note for the truly devoted Solr users, an ELK stack alternative exists with <a href="http://lucidworks.com/fusion/silk/">SiLK</a>. I highly recommend checking out Lucidworks&#8217; various blog posts on <a href="http://lucidworks.com/blog/">Solr and search in general</a>.</p>
<h2>Some background</h2>
<p>On an existing search project I use the ELK stack to ingest, analysis and visualise logs from Comperio&#8217;s search middleware application.<br />
<a href="http://blog.comperiosearch.com/wp-content/uploads/2088/09/search_logs.png"><img class="aligncenter size-medium wp-image-3942" src="http://blog.comperiosearch.com/wp-content/uploads/2088/09/search_logs-300x157.png" alt="Search Logs Dashboard" width="300" height="157" /></a><br />
Although this gave us a great view of user query behaviour, Solr logs a great more detailed information. I wanted to log indexing events, errors and the searches with all other parameters in addition to just the query string.</p>
<h2>Lets get started</h2>
<p>I&#8217;m going to assume you already have a running Solr installation. You will, however, need to download <a href="https://www.elastic.co/products/elasticsearch">Elasticsearch</a> and <a href="https://www.elastic.co/products/logstash">Logstash</a> and unpack them. Before we start Elasticsearch, I recommend installing these plugins:</p>
<ul>
<li><a href="http://mobz.github.io/elasticsearch-head/">Head</a></li>
<li><a href="https://www.elastic.co/guide/en/marvel/current/_installation.html">Marvel</a></li>
</ul>
<p>Head is a cluster health monitoring tool. Marvel we&#8217;ll only need for the bundled developer console, Sense. To disable Marvel&#8217;s other capabilities, add this line to ~/elasticsearch/config/elasticsearch.yml</p><pre class="crayon-plain-tag">marvel.agent.enabled: false</pre><p>Start elasticsearch with this command:</p><pre class="crayon-plain-tag">~/elasticsearch-[version]/bin/elasticsearch</pre><p>Navigate to <a href="http://localhost:9200/">http://localhost:9200/</a> to confirm that Elasticsearch is running. Check <a href="http://localhost:9200/_plugin/head">http://localhost:9200/_plugin/head</a> and <a href="http://localhost:9200/_plugin/marvel/sense/index.html">http://localhost:9200/_plugin/marvel/sense/index.html</a> to verify the plugins installed correctly.</p>
<h2>The anatomy of a Logstash config</h2>
<hr />
<h3>Update 21/09/15</h3>
<p>I have since greatly simplified the multiline portions of the Logstash configs. Use instead this filter section: <script src="https://gist.github.com/41ca2c34c50d0d9d8e82.js?file=solr-filter.conf"></script>The rest of the original article contents are unchanged for comparison&#8217;s sake.</p>
<hr />
<p>All Logstash configs share three main building blocks. It starts with the Input stage, which defines what the data source is and how to access it. Next is the Filter stage, which carries out data processing and extraction. Finally, the Output stage tells Logstash where to send the processed data. Lets start with the basics, the input and output stages:</p><pre class="crayon-plain-tag">input {
  file {
    path =&gt; "~/solr.log"
  }
}

filter {}

output {
  # Send directly to local Elasticsearch
  elasticsearch_http {
    host =&gt; "localhost"
    template =&gt; "~/logstash/bin/logstash_solr_template.json"
    index =&gt; "solr-%{+YYYY.MM.dd}"
    template_overwrite =&gt; true
  }</pre><p>This is one of the simpler input/output configs. We read a file at a given location and stream its raw contents to an Elasticsearch instance. Take a look at the <a href="https://www.elastic.co/guide/en/logstash/current/input-plugins.html">input</a> and <a href="https://www.elastic.co/guide/en/logstash/current/output-plugins.html">output</a> plugins&#8217; documentation for more details and default values. The index setting causes Logstash to create a new index every day with a name generated from the provided pattern. The template option tells Logstash what kind of field mapping and settings to use when creating the Elasticsearch indices. You can find the template file I used <a href="https://gist.github.com/sebnmuller/41ca2c34c50d0d9d8e82#file-solr-template-json">here</a>.</p>
<p>To process the Solr logs, we&#8217;ll use the <a href="https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html">grok</a>, <a href="https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html">mutate</a>, <a href="https://www.elastic.co/guide/en/logstash/current/plugins-filters-multiline.html">multiline</a>, <a href="https://www.elastic.co/guide/en/logstash/current/plugins-filters-drop.html">drop</a> and <a href="https://www.elastic.co/guide/en/logstash/current/plugins-filters-kv.html">kv</a> filter plugins.</p>
<ul>
<li>Grok is a regexp based parsing stage primarily used to match strings and extract parts. There are a number of default patterns described on the grok documentation page. While building your grok expressions, the <a href="https://grokdebug.herokuapp.com/">grok debugger app</a> is particularly helpful. Be mindful though that some of the escaping syntax isn&#8217;t always the same in the app as what the Logstash config expects.</li>
<li>We need the multiline plugin to link stacktraces to their initial error message.</li>
<li>The kv, aka key value, plugin will help us extract the parameters from Solr indexing and search events</li>
<li>We use mutate to add and remove tags along the way.</li>
<li>And finally, drop to drop any events we don&#8217;t want to keep.</li>
</ul>
<p>&nbsp;</p>
<h2>The <del>hard</del> fun part</h2>
<p>Lets dive into the filter stage now. Take a look at the <a href="https://gist.github.com/sebnmuller/41ca2c34c50d0d9d8e82#file-solr-logstash-conf">config file</a> I&#8217;m using. The Grok patterns may appear a bit daunting, especially if you&#8217;re not very familiar with regexp and the default Grok patterns, but don&#8217;t worry! Lets break it down.</p>
<p>The first section extracts the log event&#8217;s severity and timestamp into their own fields, &#8216;level&#8217; and &#8216;LogTime&#8217;:</p><pre class="crayon-plain-tag">grok {
    match =&gt; { "message" =&gt; "%{WORD:level}.+?- %{DATA:LogTime};" }
      tag_on_failure =&gt; []
  }</pre><p>So, given this line from my <a href="https://gist.github.com/sebnmuller/41ca2c34c50d0d9d8e82#file-solr-log">example log file</a></p><pre class="crayon-plain-tag">INFO  - 2015-09-07 15:40:34.535; org.apache.solr.update.processor.LogUpdateProcessor; [sintef_main] webapp=/ path=/update/extract params={literal.source=epifile&amp;literal.epi_file_title=GOFER+L4.0+Demonstratorer+V1.0.pdf&amp;literal.title=GOFER+L4.0+Demonstratorer+V1.0.pdf&amp;literal.id=epifile_211278&amp;literal.epifileid_s=211278&amp;literal.url=http://www.sintef.no/globalassets/upload/teknologi_samfunn/6060/prosjektfiler/gofer/gofer-l4.0-demonstratorer-v1.0.pdf&amp;stream.url=http://www.sintef.no/globalassets/upload/teknologi_samfunn/6060/prosjektfiler/gofer/gofer-l4.0-demonstratorer-v1.0.pdf&amp;literal.filesource_s=SiteFile} {} 0 65</pre><p>We&#8217;d extract</p><pre class="crayon-plain-tag">{ "level": "INFO", "LogTime":"2015-09-07 15:40:34.535"}</pre><p>In the template file I linked earlier, you&#8217;ll notice configuration for the LogTime field. Here we define for Elasticsearch a valid DateTime format. We need to do this so that Kibana recognises the field as one we can use for temporal analyses. Otherwise the only timestamp field we&#8217;d have would contain the time at which the logs were processed and stored in Elasticsearch. Although not a problem in a realtime log analyses system, if you have old logs you want to parse you will need to define this separate timestamp field. As an additional sidenote, you&#8217;ll notice I use</p><pre class="crayon-plain-tag">tag_on_failure =&gt; []</pre><p>in most of my Grok stages. The default value is &#8220;_grokparsefailure&#8221;, which I don&#8217;t need in a production system. Custom failure and success tags are very helpful to debug your Logstash configs.</p>
<p>The next little section combines commit messages into a single line. The first event in the example log file is an example of such commit messages split over three lines.</p><pre class="crayon-plain-tag"># Combine commit events into single message
  multiline {
      pattern =&gt; "^\t(commit\{)"
      what =&gt; "previous"
    }</pre><p>Now we come to a major section for handling general INFO level messages.</p><pre class="crayon-plain-tag"># INFO level events treated differently than ERROR
  if "INFO" in [level] {
    grok {
      match =&gt; {
          "message" =&gt; ".+?; ((([a-zA-Z]+(\.|;|:))+) )+?\[%{WORD:collection}\].+?path=%{DATA:endpoint} params=\{%{DATA:params}\}.+?\{%{WORD:action}=\[%{DATA:docId}"
        }
        tag_on_failure =&gt; []  
    }
    if [params] {
      kv {
        field_split =&gt; "&amp;"
        source =&gt; "params"
      }
    } else {
      grok {
        match =&gt; {
          "message" =&gt; ".+?; ((([a-zA-Z]+(\.|;|:))+) )+?commits"  
        }
        tag_on_failure =&gt; [ "drop" ]
        add_field =&gt; {
          "action" =&gt; "commit"
        }
      }
      if "drop" in [tags] {
        drop {}
      }
    }
  }</pre><p>This filter will only run on INFO level messages, due to the conditional at its beginning. The first Grok stage matches log events similar to the one above. The key fields we extract are the Solr collection/core, the endpoint we hit e.g. update/extract, the parameters supplied by the HTTP request, what action e.g. add or delete and finally the document ID. If the Grok succeeded to extract a params field, we run the key value stage, splitting no ampersand to extract each HTTP parameter. This is how a resulting document&#8217;s extracted contents look like when stored in Elasticsearch:</p><pre class="crayon-plain-tag">{
  "level": "INFO",
  "LogTime": "2015-09-07 15:40:18.938",
  "collection": "sintef_main",
  "endpoint": "/update/extract",
  "params":     "literal.source=epifile&amp;literal.epi_file_title=A05100_Tass5+Trondheim.pdf&amp;literal.title=A05100_Tass5+Trondheim.pdf&amp;literal.id=epifile_211027&amp;literal.epifileid_s=211027&amp;literal.url=http://www.sintef.no/globalassets/upload/teknologi_samfunn/5036/a05100_tass5-trondheim.pdf&amp;stream.url=http://www.sintef.no/globalassets/upload/teknologi_samfunn/5036/a05100_tass5-trondheim.pdf&amp;literal.filesource_s=SiteFile",
  "action": "add",
  "docId": "epifile_211027",
  "version": "1511661994131849216",
  "literal.source": "epifile",
  "literal.epi_file_title": "A05100_Tass5+Trondheim.pdf",
  "literal.title": "A05100_Tass5+Trondheim.pdf",
  "literal.id": "epifile_211027",
  "literal.epifileid_s": "211027",
  "literal.url": "http://www.sintef.no/globalassets/upload/teknologi_samfunn/5036/a05100_tass5-trondheim.pdf",
  "stream.url": "http://www.sintef.no/globalassets/upload/teknologi_samfunn/5036/a05100_tass5-trondheim.pdf",
  "literal.filesource_s": "SiteFile"
}</pre><p>If the Grok did not extract a params field, I want to identify possible commit messages with the following Grok. If this one fails we tag messages with &#8220;drop&#8221;. Finally, any messages tagged with &#8220;drop&#8221; are dropped for the pipeline. I specifically created these Grok patterns to match indexing and commit messages as I already track queries at the middleware layer in our stack. If you want to track queries at the Solr level, simply use this pattern:</p><pre class="crayon-plain-tag">.+?; ((([a-zA-Z]+(\.|;|:))+) )+?\[%{WORD:collection}\].+?path=%{DATA:endpoint} params=\{%{DATA:params}\} hits=%{INT:hits} status=%{INT:status} QTime=%{INT:queryTime}</pre><p>The next section handles ERROR level messages:</p><pre class="crayon-plain-tag"># Error event implies stack track, which requires multiline parsing
  if "ERROR" in [level] {
    multiline {
      pattern =&gt; "^\s"
      what =&gt; "previous"
      add_tag =&gt; [ "multiline_pre" ]
    }
    multiline {
        pattern =&gt; "^Caused by"
        what =&gt; "previous"
        add_tag =&gt; [ "multiline_post" ]
    }
    if "multiline_post" in [tags] {
      grok {
        match =&gt; {
          "message" =&gt; ".+?; ((([a-zA-Z]+(\.|;|:))+) )+%{DATA:reason}(\n\t)((.+?Caused by: ((([a-zA-Z]+(\.|;|:))+) )+)%{DATA:reason}(\n\t))+"
        }
        tag_on_failure =&gt; []
      }
    }
  }</pre><p>Given a stack trace, there&#8217;s a few in the example log file, this stage first combines all the lines of the stack trace into a single message. It then extracts the first and the last causes. The assumption being the first message is the high level failure message and the last one the actual underlying cause.</p>
<p>Finally, I drop any empty lines and clean up temporary tags:</p><pre class="crayon-plain-tag"># Remove intermediate tags, and multiline added randomly by multiline stage
  mutate {
      remove_tag =&gt; [ "multiline_pre", "multiline_post", "multiline" ]
  }
  # Drop empty lines
  if [message] =~ /^\s*$/ {
    drop {}
  }</pre><p>To check you have succesfully processed your Solr logs, open up the Sense plugin and run this query:</p><pre class="crayon-plain-tag"># aggregate on level
GET solr-*/_search
{
  "query": {
    "match_all": {}
  },
  "size": 10,
  "aggs": {
    "action": {
      "terms": {
        "field": "level",
        "size": 10
      }
    }
  }
}</pre><p>You should get back all your processed log events along with an aggregation on event severity.</p>
<h2>Conclusion</h2>
<p>Solr logs contain a great deal of useful information. With the ELK stack you can extract, store, analyse and visualise this data. I hope I&#8217;ve given you some helpful tips on how to start doing so! If you run into any problems, please get in touch in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2015/09/21/solr-logstash-analysis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Elasticsearch: Shield protected Kibana with Active Directory</title>
		<link>http://blog.comperiosearch.com/blog/2015/08/21/elasticsearch-security-shield/</link>
		<comments>http://blog.comperiosearch.com/blog/2015/08/21/elasticsearch-security-shield/#comments</comments>
		<pubDate>Fri, 21 Aug 2015 14:26:45 +0000</pubDate>
		<dc:creator><![CDATA[Christoffer Vig]]></dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[Kibana]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=3245</guid>
		<description><![CDATA[Elasticsearch easily stores terabytes of data, but how can you make sure users only see the data they should? This post will explore how to use Shield, a plugin for Elasticsearch, to authenticate users with Active Directory. Elasticsearch will by default allow anyone access to all data. The Shield plugin allows locking down Elasticsearch using authentication [...]]]></description>
				<content:encoded><![CDATA[<p>Elasticsearch easily stores terabytes of data, but how can you make sure users only see the data they should? This post will explore how to use Shield, a plugin for Elasticsearch, to authenticate users with Active Directory.</p>
<p><span id="more-3245"></span><br />
<a title="NO TRESPASSING" href="https://www.flickr.com/photos/mike2099/2058021162/in/photolist-48RTZu-4ttdcn-4YPqqU-5WbRAP-8rYugF-XsCao-ftZ1hL-dpmFB-dqyeUE-bjV3VY-bEMba3-bEMb6w-84YCqg-rf5Yk1-8Yjaj3-chg68s-4KDN1M-4KDMWF-5MfWjA-tCJt6J-8nxBiZ-6YsUyh-KfDRK-54uLmy-bv1Pv-oChdLk-pL3X8t-4RTTjd-dhfUPn-cEkCFY-czjXiE-m1zThD-dzESFD-oj2KUM-c16MV-72dTxS-g4Yky4-kK9YR-p6DYnY-5HJvrX-8aovPQ-dhfVkP-bwB8c-gFzTXk-7zd9iF-eua6KC-2gzEc-8nxtcH-2gzEb-fnp3zH" data-flickr-embed="true"><img src="https://farm3.staticflickr.com/2059/2058021162_ed7b6e8d72_b.jpg" alt="NO TRESPASSING" width="600" /></a><script src="//embedr.flickr.com/assets/client-code.js" async="" charset="utf-8"></script></p>
<p>Elasticsearch will by default allow anyone access to all data. The <a href="https://www.elastic.co/guide/en/shield/current/introduction.html">Shield</a> plugin allows locking down Elasticsearch using authentication from the internal esusers realm, Active Directory (AD)  or LDAP . Using AD, you can map groups defined in your Windows domain to roles in Elasticsearch. For instance, you can allow people in the Fishery department access only to  fish-indexes, and give complete control to anyone in the IT department.</p>
<p>To use Shield in production, you have to buy an Elasticsearch subscription, however, you get a 30-day trial when installing the license manager. So let&#8217;s hurry up and see how this works out in Kibana.</p>
<p>&nbsp;</p>
<p>In this post, we will install Shield and connect to Active Directory (AD) for authentication. After having made sure we can authenticate with AD, we will add SSL encryption everywhere possible. We will add authentication for the Kibana server using the built in authentication realm esusers, and if time allows at the end, we will create two user groups, each with access to its own index, and check how it all looks when accessed in Kibana 4.</p>
<p>&nbsp;</p>
<h3>Prerequisites</h3>
<p>You will need a previously installed Elasticsearch and Kibana. The most recent versions should work, I have used Elasticsearch 1.7 and Kibana 4.1.1  If you need a machine to test on, I can personally recommend the vagrant-elk-box you can find <a href="https://github.com/comperiosearch/vagrant-elk-box-ansible">here</a>: <strong>The following guide assumes the file locations of the vagrant-elk-box</strong>, if you install differently, you will probably know where to look. Ask an adult for help.</p>
<p>For Active Directory, you need to be on a domain that uses Active Directory. That would probably mean some kind of Windows work environment.</p>
<p>&nbsp;</p>
<h4>Installing Shield</h4>
<p>If you&#8217;re on the vagrant box you should begin the lesson by entering the vagrant box using the commands</p><pre class="crayon-plain-tag">vagrant up
vagrant ssh</pre><p>&nbsp;</p>
<p>Install the license manager</p><pre class="crayon-plain-tag"> sudo /usr/share/elasticsearch/bin/plugin -i elasticsearch/license/latest</pre><p>Install Shield</p><pre class="crayon-plain-tag"> sudo /usr/share/elasticsearch/bin/plugin -i elasticsearch/shield/latest</pre><p>Restart elasticsearch. (service elasticsearch restart)</p>
<p>Check out the logs,  you should find some information regarding when your Shield license will expire (logfile location:  /var/log/elasticsearch/vagrant-es.log)</p>
<h4>Integrating Active Directory</h4>
<p>The next step involves figuring out a thing or two about your Active Directory configuration. First of all you need to know the address. Now you need to be on  your windows machine, open cmd.exe and type</p><pre class="crayon-plain-tag">set LOGONSERVER</pre><p>The name of your AD should pop back.  Add a section similar to the following into the elasticsearch.yml file (at /etc/elasticsearch/elasticsearch.yml)</p><pre class="crayon-plain-tag">shield.authc.realms:
  active_directory:
    type: active_directory
    domain_name: superdomain.com
    unmapped_groups_as_roles: true
    url: ldap://ad.superdomain.com</pre><p>Type in the address to your AD in the url: field (where it says url: ldap://ad.superdomain.com). If your logonserver is ad.cnn.com, you should type in url: ldap://ad.cnn.com</p>
<p>Also, you need to figure out your domain name and type it in correctly.</p>
<p>NB: Be careful with the indenting! Elasticsesarch cares a lot about correct indenting, and may even refuse to start without telling you why if you make a mistake.</p>
<h5>Finding the Correct name for the Active Directory group</h5>
<p>Next step involves figuring out the name for the Group you wish to grant access to. You may have called your group &#8220;Fishermen&#8221;, but that is probably not exactly what it&#8217;s called in AD.</p>
<p>Microsoft has a very simple and nice tool called <a href="https://technet.microsoft.com/en-us/library/bb963907.aspx">Active Directory Explorer</a> . Open the tool and enter the adress you just found from the LOGONSERVER (remember? it&#8217;s only 10 lines above)</p>
<p>You may have to click and explore a little to find the groups you want. Once you find it, you need the value for the &#8220;distinguishedName&#8221; attribute. You can double click on it and copy out from the &#8220;Object&#8221;.</p>
<p>This is an example from my AD</p><pre class="crayon-plain-tag">CN=Rolle IT,OU=Groups,OU=Oslo,OU=Comperiosearch,DC=comperiosearch,DC=com</pre><p>Now this value represents a group which we want to map to a role in elasticsearch.</p>
<p>Open the file /etc/elasticsearch/shield/role-mapping.yml. It should look similar to this</p><pre class="crayon-plain-tag"># Role mapping configuration file which has elasticsearch roles as keys
# that map to one or more user or group distinguished names

#roleA:   this is an elasticsearch role
#  - groupA-DN  this is a group distinguished name
#  - groupB-DN
#  - user1-DN   this is the full user distinguished name
power_user:
  - "CN=Rolle IT,OU=Groups,OU=Oslo,OU=Comperiosearch,DC=comperiosearch,DC=com"
#user:
# - "cn=admins,dc=example,dc=com" 
# - "cn=John Doe,cn=other users,dc=example,dc=com"</pre><p>I have uncommented the line with &#8220;power_user:&#8221; and added a line below containing the distinguishedName from above.</p>
<p>By restarting elasticsearch, anyone in the &#8220;Rolle IT&#8221; group should now be able to log in (and nobody else (yet)).</p>
<p>To test it out, open <a href="http://localhost:9200">http://localhost:9200</a> in your browser. You should be presented with a login box where you can type in your username/password. In case of failure, check out the elasticsearch logs (at /var/log/elasticsearch/vagrant-es.log).</p>
<p>If you were able to log in, that means Active Directory authentication works. Congratulations!  You deserve a refreshment. Some strong coffee, will go down well with the next sections, where we add encrypted communications everywhere we can.</p>
<h3>SSL  - Elasticsearch</h3>
<p>Authentication and encrypted communication go hand in hand. Without SSL, username and password is transferred in plaintext on the wire. For this demo we will use self-signed certificates. Keytool comes with Java, and is used to handle certificates for Elasticsearch.  The following command will generate a self-signed certficate and put it in a JKS file named self-signed.jks. (swap out  $password with your preferred password)</p><pre class="crayon-plain-tag">keytool -genkey -keyalg RSA -alias selfsigned -keystore self-signed.jks -keypass $password -storepass $password -validity 360 -keysize 2048 -dname "CN=localhost, OU=orgUnit, O=org, L=city, S=state, C=NO"</pre><p>Copy the certificate into /etc/elasticsearch/</p>
<p>Modify  /etc/elasticsearch/elasticsearch.yml by adding the following lines:</p><pre class="crayon-plain-tag">shield.ssl.keystore.path: /etc/elasticsearch/self-signed.jks
shield.ssl.keystore.password: $password
shield.ssl.hostname_verification: false
shield.transport.ssl: true
shield.http.ssl: true</pre><p>(use the same password as you used when creating the self-signed certificate )</p>
<p>Restart Elasticsearch again, and watch the logs for failures.</p>
<p>Try to open https://localhost:9200 in your browser (NB: httpS not http)</p>
<div id="attachment_3905" style="width: 310px" class="wp-caption alignright"><img class="wp-image-3905 size-medium" src="http://blog.comperiosearch.com/wp-content/uploads/2015/08/your-connection-is-not-private-e1440146932126-300x181.png" alt="your connection is not private" width="300" height="181" /><p class="wp-caption-text">https://localhost:9200</p></div>
<p>You should a screen warning you that something is wrong with the connection. This is a good sign! It means your certificate is actually working! For production use you could use your own CA or buy a proper certificate, which both will avoid the ugly warning screen.</p>
<h4>SSL &#8211; Active directory</h4>
<p>Our current method of connecting to Active Directory is unencrypted &#8211; we need to enable SSL for the AD connections.</p>
<p>1. Fetch the certificate from your Active Directory server (replace ldap.example.com with the LOGONSERVER from above)</p><pre class="crayon-plain-tag">echo | openssl s_client -connect ldap.example.com:6362&gt;/dev/null| openssl x509 &gt; ldap.crt</pre><p>2. Import the certificate into your keystore (located at /etc/elasticsearch/)</p><pre class="crayon-plain-tag">keytool -import-keystore self-signed.jks -file ldap.crt</pre><p>&nbsp;</p>
<p>3. Modify AD url in elasticsearch.yml<br />
change the line</p><pre class="crayon-plain-tag">url: ldap://ad.superdomain.com</pre><p>to</p><pre class="crayon-plain-tag">url: ldaps://ad.superdomain.com</pre><p>Restart elasticsearch and check logs for failures</p>
<h4>Kibana authentication with esusers</h4>
<p>With Elasticsearch locked down by Shield, it means no services can search or post data either. Including Kibana and Logstash.</p>
<p>Active Directory is great, but I&#8217;m not sure I want to use it for letting the Kibana server talk to Elasticsearch. We can use the Shield built in user management system, esusers. Elasticsearch comes with a set of predefined roles, including roles for Logstash, Kibana4 server and Kibana4 user. (/etc/elasticsearch/shield/role-mapping.yml on the vagrant-elk box if you&#8217;re still on that one).</p>
<p>Add a new kibana4_server user, granting it the role kibana4_server, using this command:</p><pre class="crayon-plain-tag">cd /usr/share/elasticsearch/bin/shield  
./esusers useradd kibana4_server -p secret -r kibana4_server</pre><p></p>
<h4></h4>
<h4>Adding esusers realm</h4>
<p>The esusers realm is the default one, and does not need to be configured if that&#8217;s the only realm you use. Now since we added the Active Directory realm we must add another section to the elasticsearch.yml file from above.</p>
<p>It should end up looking like this</p><pre class="crayon-plain-tag">shield.authc.realms:
  esusers:
    type: esusers
    order: 0
  active_directory:
    order: 1
    type: active_directory
    domain_name: superdomain.com
    unmapped_groups_as_roles: true
    url: ldap://ad.superdomain.com</pre><p>The order parameter defines in what order elasticsearch should try the various authentication mechanisms.</p>
<h4>Allowing Kibana to access Elasticsearch</h4>
<p>Kibana must be informed of the new user we just created. You will find the kibana configuration file at /opt/kibana/config/kibana.yml.</p>
<p>Add in the username and password you just created. You also need to change the address for elasticsearch to using https</p><pre class="crayon-plain-tag"># The Elasticsearch instance to use for all your queries.
elasticsearch_url: "https://localhost:9200"

# If your Elasticsearch is protected with basic auth, this is the user credentials
# used by the Kibana server to perform maintence on the kibana_index at statup. Your Kibana
# users will still need to authenticate with Elasticsearch (which is proxied thorugh
# the Kibana server)
kibana_elasticsearch_username: kibana4_server
kibana_elasticsearch_password: secret</pre><p>Restart kibana and elasticsearch, and watch the logs for any errors. Try opening Kibana at  http://localhost:5601, type in your login and password. Provided you&#8217;re in the group you gave access earlier, you should be able to login.</p>
<h4></h4>
<h4>Creating SSL for Kibana</h4>
<p>Once you have enabled authorization for Elasticsearch, you really need to set SSL certificates for Kibana as well. This is also configured in kibana.yml</p><pre class="crayon-plain-tag">verify_ssl: false
# SSL for outgoing requests from the Kibana Server (PEM formatted)
ssl_key_file: "kibana_ssl_key_file"
ssl_cert_file: "kibana_ssl_cert_file"</pre><p>You can create a self-signed key and cert file for kibana using the following command:</p><pre class="crayon-plain-tag">openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes</pre><p>&nbsp;</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/08/kibana-auth.png"><img class="alignright size-medium wp-image-3920" src="http://blog.comperiosearch.com/wp-content/uploads/2015/08/kibana-auth-300x200.png" alt="kibana auth" width="300" height="200" /></a></p>
<h4>Configuring AD groups for Kibana access</h4>
<p>Unfortunately, this part of the post is going to be very sketchy, as we are desperately running out of time. This blog is much too long already.</p>
<p>Elasticsearch already comes with a list of predefined roles, among which you can find the kibana4 role.  The kibana4 role allows read/write access to the .kibana index, in addition to search and read access to all indexes. We want to limit access to just one index for each AD group. The fishery group shall only access the fishery index, and the finance group shall only acess the finance index. We can create roles that limit access to one index by copying the kibana4 role, giving it an appropriate name and changing the index:&#8217;*&#8217; section to map to only the preferred index.</p>
<p>The final step involves mapping the Elasticsearch role into an AD role. This is done in the role_mapping.yml file, as mentioned above.</p>
<p>Only joking of course, that wasn&#8217;t the last step. The last step is restarting Elasticsearch, and checking the logs for failures as you try to log in.</p>
<p>&nbsp;</p>
<h3>Securing Elasticsearch</h3>
<p>Shield brings enterprise authentication to Elasticsearch. You can easily manage access to various parts of  Elasticsearch management and data by using Active Directory groups.</p>
<p>This has been a short dive into the possibilities, make sure to contact Comperio if you should need  help in creating a solution with Elasticsearch and Shield.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2015/08/21/elasticsearch-security-shield/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Voting patterns at the Norwegian parliament</title>
		<link>http://blog.comperiosearch.com/blog/2015/07/30/voting-patterns-at-the-norwegian-parliament/</link>
		<comments>http://blog.comperiosearch.com/blog/2015/07/30/voting-patterns-at-the-norwegian-parliament/#comments</comments>
		<pubDate>Thu, 30 Jul 2015 11:42:37 +0000</pubDate>
		<dc:creator><![CDATA[André Lynum]]></dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[PCA]]></category>
		<category><![CDATA[visualization]]></category>
		<category><![CDATA[word analysis]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=3858</guid>
		<description><![CDATA[A couple of weeks ago we saw the blog post visualizing the voting patterns in the Polish parliament. In anticipation of the upcoming election and in the interest of checking up on our elected representatives we thought we would do a similar analysis for the Norwegian parliament. First we will visualize a projection of the voting data [...]]]></description>
				<content:encoded><![CDATA[<p><img class="alignnone" src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/Stortinget%2C_Oslo%2C_Norway_%28cropped%29.jpg/640px-Stortinget%2C_Oslo%2C_Norway_%28cropped%29.jpg" alt="By Stortinget,_Oslo,_Norway.jpg: gcardinal from Norway (Stortinget,_Oslo,_Norway.jpg) [CC BY 2.0 (http://creativecommons.org/licenses/by/2.0)], via Wikimedia Commons" width="640" height="290" /></p>
<p style="color: #000000">A couple of weeks ago we saw the blog <a style="color: #337ab7" href="https://marcinciura.wordpress.com/2015/07/01/the-vector-space-of-the-polish-parliament-in-pictures/" target="_blank">post</a> visualizing the voting patterns in the Polish parliament. In anticipation of the upcoming election and in the interest of checking up on our elected representatives we thought we would do a similar analysis for the Norwegian parliament. First we will visualize a projection of the voting data of the Norwegian parliament into 3D, and then we will try to interpret the axes of the projection in terms of the issues voted on.</p>
<h2 id="The-data" style="color: #000000">The data</h2>
<p style="color: #000000">Stortinget, the Norwegian parliament, has a nice <a style="color: #337ab7" href="http://data.stortinget.no/" target="_blank">web service</a> for retrieving details about the process an issue passes through in the parliament. Proposals, committees, referendums and so on; there is a surprising amount of detail in there. With a bit of work we pulled out the individual votes for the parliamentary referendums we were able to access. On the less bright side the data doesn&#8217;t appear to be complete as far as we can see, and there is also a range of documented caveats and restrictions regarding which votes are actually registered in the system. This reduces the usefulness of any detailed analysis based on this data, but we still think the aggregated picture one can create is both interesting and valid.</p>
<p style="color: #000000">The voting data comes in the form of for, against or abstained votes. Like in the referenced blog post we would like to visualize the similarity in voting patterns for the representatives. In order to do this we constructed a grid of referendums versus representatives for the current parliamentary period with a single cell representing a vote encoded as 1 for &#8220;for&#8221;, -1 for &#8220;against&#8221; and 0 if &#8220;abstained&#8221; which makes this a neutral midpoint in the analysis we are going to do. This gives a data point for each representative in the multidimensional &#8220;vote space&#8221; where we can do things like clustering or similarity measures to find patterns in the votes.</p>
<h2 id="Visualizing-the-vote-space" style="color: #000000">Visualizing the vote space</h2>
<p style="color: #000000">Since we have the records for 58 referendums so far in the 2013-2017 period and 612 records in the 2009-2013 period we cannot directly visualize our representatives in the vote space. There are several techniques for projecting data like this into lower dimensional sub-spaces while still retaining the essential characteristics of the data. In this blog post we will project the voting data into 3 dimensions using Principal Components Analysis. There are several alternatives here and we chose PCA for the following reasons.</p>
<ul style="color: #000000">
<li>Our data is categorical, but non-binary. It is also distributed symmetrically with 0 representing a neutral value. One would expect that categorical data would not necessarily be modeled well by PCA, but the symmetry and the consistent values involved combined with the density of the data suggests that PCA should behave well.</li>
<li>PCA is based on Singular Value Decomposition (SVD) of the co-variance matrix and consequently has properties that are straightforward to interpret compared to methods such as Multidimensional Scaling (MDS) which seeks to preserve the individual distances between data points.</li>
<li>PCA gives us a projection along axes which have the most variance which in our case should highlight the parts of the data where there is less agreement between parties or representatives. This disagreement is the sort of contrast that we seek to visualize.</li>
<li>PCA axes are linear combinations of the separate referendums which means we can create a comprehensible interpretation of the visualization in terms of political issues.</li>
</ul>
<p style="color: #000000">Other methods are generally harder to interpret with regard to their applicability and the resulting projections (like probabilistic methods such as ICA) or don&#8217;t highlight the contrast we want to visualize (like MDS which preserves the distance relationships between the representatives).</p>
<h2 id="The-plots">The plots</h2>
<p>We&#8217;re just going to present the plots without any political commentary. The first plot is for the current parliamentary period while the second is for the previous period. In the first we have highlighted Miljøpartiet De Grønne which only has a single representative in the current parliament. It is interesting to note the coherence of certain coalition partners in government and the location of the centrist parties. An important measure for the PCA projection is the explained variance ratio of the axes. This is the amount of variance that is preserved in the projected axes and is a measure of how much of the original information is retained in the projection. For our plots the total explained variance is ca. 62% and 57% which means there is quite a bit of diversity in the voting patterns that is not shown in the plot but still enough to consider them informative. The axes are ordered by explained variance so that the first axis explains over 40% of the variance while the remaining two around 10% each.</p>
<div id="attachment_3860" style="width: 610px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/no-parliament-votes-2013-2015.png"><img class="wp-image-3860" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/no-parliament-votes-2013-2015-1024x619.png" alt="no-parliament-votes-2013-2015" width="600" height="363" /></a><p class="wp-caption-text">Projection of voting patterns in the 2013-2015 parliamentary periods.</p></div>
<h2></h2>
<div id="attachment_3859" style="width: 610px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/no-parliament-votes-2009-2013.png"><img class="wp-image-3859" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/no-parliament-votes-2009-2013.png" alt="no-parliament-votes-2009-2013" width="600" height="363" /></a><p class="wp-caption-text">Projection of voting patterns in the 2009-2013 parliamentary periods.</p></div>
<h2 id="Interpreting-the-projection-axes">Interpreting the projection axes</h2>
<p>In and of itself the colorful dots have a limited story to tell. If we could characterize what the axes in the graphs represent we could draw more interesting and detailed inferences. What we will do here is mostly for illustrative purposes though, since it really requires someone knowledgeable in Norwegian parliamentary politics and procedure to build an analysis with proper grounding in actual political activity. Here we will just play around with the data. It is tempting to treat the positive and negative directions of the axes as affirmative/negative on an issue but we would have to look at the text for each referendum to see what &#8220;for&#8221; and &#8220;against&#8221; actually means with regards to the sentiment on each issue. Actually the same issue tend to have both strong positive and negative components in a projected axis which strongly suggests that there isn&#8217;t a single sentiment expressed by the axis direction. Can we create a credible summary of the axes without closely studying each referendum and each issue? Each referendum is part of an issue and it turns out each issue has a list of topics associated with it. So we can make a summary of how much each topic is represented in an axis by the weight for each vote on this issue in a given axis. Each axis is a linear component of the votes and we add up the absolute value of each vote that is part of an issue concerning the topic. To class up this blog a bit we decided to make a word cloud out of the results.</p>
<div id="attachment_3880" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-3.png"><img class="wp-image-3880 size-medium" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-3-300x150.png" alt="parliament-wordcloud-3" width="300" height="150" /></a><p class="wp-caption-text">Word cloud for PCA component 1 for the 2013-2015 plot.</p></div>
<div id="attachment_3879" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-2.png"><img class="size-medium wp-image-3879" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-2-300x150.png" alt="Word cloud for PCA component 2 for the 2013-2015 plot." width="300" height="150" /></a><p class="wp-caption-text">Word cloud for PCA component 2 for the 2013-2015 plot.</p></div>
<div id="attachment_3878" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-1.png"><img class="size-medium wp-image-3878" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-1-300x150.png" alt="Word cloud for PCA component 3 for the 2013-2015 plot." width="300" height="150" /></a><p class="wp-caption-text">Word cloud for PCA component 3 for the 2013-2015 plot.</p></div>
<h3 id="The-most-characteristic-topics" style="color: #000000">The most characteristic topics</h3>
<p style="color: #000000">Some topics account for most of the activity in parliament and tend to dominate the data if we look only at the volume of votes. For the present parliamentary period the data is rather sparse so this isn&#8217;t as pronounced in the word clouds, but for the 2009-2013 period where there is a lot more data transportation/communication and health dominates in all the axes. Can we see what topics are characteristic for an axis instead? To highlight topics that have a high overall weight in our projection in comparison to their overall presence in the referendums we weigh each topic by its &#8220;Inverse Topic Frequency&#8221; &#8211; similar to the common Inverse Document Frequency (IDF) common in search relevance and information retrieval. This makes rarer but highly weighted topics stand out. This weighting gives us a clearer picture of how the axes differ from each other, even if they don&#8217;t necessarily show the ratio of influence of these topics on the projection itself.</p>
<div id="attachment_3881" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-4.png"><img class="size-medium wp-image-3881" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-4-300x150.png" alt="Contrastive word cloud for PCA component 1 for the 2009-2013 plot." width="300" height="150" /></a><p class="wp-caption-text">Contrastive word cloud for PCA component 1 for the 2009-2013 plot.</p></div>
<div id="attachment_3882" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-5.png"><img class="size-medium wp-image-3882" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-5-300x150.png" alt="Contrastive word cloud for PCA component 2 for the 2009-2013 plot." width="300" height="150" /></a><p class="wp-caption-text">Contrastive word cloud for PCA component 2 for the 2009-2013 plot.</p></div>
<div id="attachment_3883" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-6.png"><img class="size-medium wp-image-3883" src="http://blog.comperiosearch.com/wp-content/uploads/2015/07/parliament-wordcloud-6-300x150.png" alt="Contrastive word cloud for PCA component 3 for the 2009-2013 plot." width="300" height="150" /></a><p class="wp-caption-text">Contrastive word cloud for PCA component 3 for the 2009-2013 plot.</p></div>
<h2 id="Wrapping-up">Wrapping up</h2>
<p>While the plots shown here are both interesting and entertaining there are many possibilities available when creating these visualizations and interpreting them. Consequently while they can be very helpful during analysis and point out interesting directions one might not have noticed otherwise, a purely quantitative analysis can fall prey to  &#8220;researchers degrees of freedom&#8221; and steer conclusions towards predetermined biases and worse. External validation and domain expertise can help ground models and inferences in reality. With the help of a domain expert we could shape the data into a format more amenable for analysis, for example by weighting issues by importance and normalizing the vote sentiment across referendums. This would provide us with a much firmer foundation for making inferences than the raw data by itself as we have done here.</p>
<h2 id="The-plots"></h2>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2015/07/30/voting-patterns-at-the-norwegian-parliament/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Elasticsearch calculates significant terms</title>
		<link>http://blog.comperiosearch.com/blog/2015/06/10/how-elasticsearch-calculates-significant-terms/</link>
		<comments>http://blog.comperiosearch.com/blog/2015/06/10/how-elasticsearch-calculates-significant-terms/#comments</comments>
		<pubDate>Wed, 10 Jun 2015 11:02:28 +0000</pubDate>
		<dc:creator><![CDATA[André Lynum]]></dc:creator>
				<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[aggregations]]></category>
		<category><![CDATA[lexical analysis]]></category>
		<category><![CDATA[relevance]]></category>
		<category><![CDATA[significant terms]]></category>
		<category><![CDATA[word analysis]]></category>

		<guid isPermaLink="false">http://blog.comperiosearch.com/?p=3785</guid>
		<description><![CDATA[Many of you who use Elasticsearch may have used the significant terms aggregation and been intrigued by this example of fast and simple word analysis. The details and mechanism behind this aggregation tends to be kept rather vague however and couched in terms like &#8220;magic&#8221; and the commonly uncommon. This is unfortunate since developing informative [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_3823" style="width: 310px" class="wp-caption aligncenter"><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/06/uncommonlycommon.png"><img src="http://blog.comperiosearch.com/wp-content/uploads/2015/06/uncommonlycommon-300x187.png" alt="The &quot;unvommonly common&quot;" width="300" height="187" class="size-medium wp-image-3823" /></a><p class="wp-caption-text">The magic of the &#8220;uncommonly common&#8221;.</p></div>
<p>Many of you who use Elasticsearch may have used the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html" title="significant terms">significant terms aggregation</a> and been intrigued by this example of fast and simple word analysis. The details and mechanism behind this aggregation tends to be kept rather vague however and couched in terms like &#8220;magic&#8221; and the commonly uncommon. This is unfortunate since developing informative analyses based on this aggregation requires some adaptation to the underlying documents especially in the face of less structured text. Significant terms seems especially susceptible to garbage in &#8211; garbage out effects and developing a robust analysis requires some understanding of the underlying data. In this blog post we will take a look at the default relevance score used by the significance terms aggregation, the mysteriously named JLH score, as it is implemented in Elasticsearch 1.5. This score is especially developed for this aggregation and experience shows that it tends to be the most effective one available in Elasticsearch at this point.</p>
<p>The JLH relevance scoring function is not given in the documentation. A quick dive into the code however and we find the following scoring function.</p>
<img src='http://s0.wp.com/latex.php?latex=++JLH+%3D+%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D++%28p_%7Bfore%7D+-+p_%7Bback%7D%29%5Cfrac%7Bp_%7Bfore%7D%7D%7Bp_%7Bback%7D%7D+%26+p_%7Bfore%7D+-+p_%7Bback%7D+%3E+0+%5C%5C++0++%26+elsewhere++%5Cend%7Bmatrix%7D%5Cright.++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  JLH = \left\{\begin{matrix}  (p_{fore} - p_{back})\frac{p_{fore}}{p_{back}} &amp; p_{fore} - p_{back} &gt; 0 \\  0  &amp; elsewhere  \end{matrix}\right.  ' title='  JLH = \left\{\begin{matrix}  (p_{fore} - p_{back})\frac{p_{fore}}{p_{back}} &amp; p_{fore} - p_{back} &gt; 0 \\  0  &amp; elsewhere  \end{matrix}\right.  ' class='latex' />
<p>Here the <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> is the frequency of the term in the foreground (or query) document set, while <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> is the term frequency in the background document set which by default is the whole index.</p>
<p>Expanding the formula gives us the following which is quadratic in <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' />.</p>
<img src='http://s0.wp.com/latex.php?latex=++%28p_%7Bfore%7D+-+p_%7Bback%7D%29%5Cfrac%7Bp_%7Bfore%7D%7D%7Bp_%7Bback%7D%7D+%3D+%5Cfrac%7Bp_%7Bfore%7D%5E2%7D%7Bp_%7Bback%7D%7D+-+p_%7Bfore%7D++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  (p_{fore} - p_{back})\frac{p_{fore}}{p_{back}} = \frac{p_{fore}^2}{p_{back}} - p_{fore}  ' title='  (p_{fore} - p_{back})\frac{p_{fore}}{p_{back}} = \frac{p_{fore}^2}{p_{back}} - p_{fore}  ' class='latex' />
<p>By keeping <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> fixed and keeping in mind that both it and <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> is positive we get the following function plot. Note that <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> is unnaturally large for illustration purposes.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/06/JLH-pb-fixed.png"><img src="http://blog.comperiosearch.com/wp-content/uploads/2015/06/JLH-pb-fixed-300x206.png" alt="JLH-pb-fixed" width="300" height="206" class="alignnone size-medium wp-image-3792"></a></p>
<p>On the face of it this looks bad for a scoring function. It can be undesirable that it changes sign, but more troublesome is the fact that this function is not monotonically increasing.</p>
<p>The gradient of the function:</p>
<img src='http://s0.wp.com/latex.php?latex=++%5Cnabla+JLH%28p_%7Bfore%7D%2C+p_%7Bback%7D%29+%3D+%5Cleft%28%5Cfrac%7B2+p_%7Bfore%7D%7D%7Bp_%7Bback%7D+-+1%7D+%2C+-%5Cfrac%7Bp_%7Bfore%7D%5E2%7D%7Bp_%7Bback%7D%5E2%7D%5Cright%29++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  \nabla JLH(p_{fore}, p_{back}) = \left(\frac{2 p_{fore}}{p_{back} - 1} , -\frac{p_{fore}^2}{p_{back}^2}\right)  ' title='  \nabla JLH(p_{fore}, p_{back}) = \left(\frac{2 p_{fore}}{p_{back} - 1} , -\frac{p_{fore}^2}{p_{back}^2}\right)  ' class='latex' />
<p>Setting the gradient to zero we see by looking at the second coordinate that the JLH does not have a minimum, but approaches it when <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> approaches zero where the function is undefined. While the second coordinate is always positive, the first coordinate shows us where the function is not increasing.</p>
<img src='http://s0.wp.com/latex.php?latex=++%5Cbegin%7Baligned%7D++%5Cfrac%7B2+p_%7Bfore%7D%7D%7Bp_%7Bback%7D%7D++-+1+%26+%3C+0+%5C%5C++p_%7Bfore%7D+%26+%3C+%5Cfrac%7B1%7D%7B2%7Dp_%7Bback%7D++%5Cend%7Baligned%7D++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  \begin{aligned}  \frac{2 p_{fore}}{p_{back}}  - 1 &amp; &lt; 0 \\  p_{fore} &amp; &lt; \frac{1}{2}p_{back}  \end{aligned}  ' title='  \begin{aligned}  \frac{2 p_{fore}}{p_{back}}  - 1 &amp; &lt; 0 \\  p_{fore} &amp; &lt; \frac{1}{2}p_{back}  \end{aligned}  ' class='latex' />
<p>Furtunately the decreasing part of the function is in an area where <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D+-+p_%7Bback%7D+%3C+0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore} - p_{back} &lt; 0' title='p_{fore} - p_{back} &lt; 0' class='latex' /> and the JLH score explicitly defined as zero. By symmetry of the square around the minimum of the first coordinate of the gradient around <img src='http://s0.wp.com/latex.php?latex=%5Cfrac%7B1%7D%7B2%7Dp_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{1}{2}p_{back}' title='\frac{1}{2}p_{back}' class='latex' /> we also see that the entire area where the score is below zero is in this region.</p>
<p>With this it seems sensible to just drop the linear term of the JLH score and just use the quadratic part. This will result in the same ranking with a slightly less steep increase in score as <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> increases.</p>
<img src='http://s0.wp.com/latex.php?latex=++JLH_%7Bmod%7D+%3D+%5Cfrac%7Bp_%7Bfore%7D%5E2%7D%7Bp_%7Bback%7D%7D++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  JLH_{mod} = \frac{p_{fore}^2}{p_{back}}  ' title='  JLH_{mod} = \frac{p_{fore}^2}{p_{back}}  ' class='latex' />
<p>Looking at the level sets for the JLH score there is a quadratic relationship between the <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' />. Solving for a fixed level <img src='http://s0.wp.com/latex.php?latex=k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='k' title='k' class='latex' /> we get:</p>
<img src='http://s0.wp.com/latex.php?latex=++%5Cbegin%7Baligned%7D++JLH+%3D+%26+%5Cfrac%7Bp_%7Bfore%7D%5E2%7D%7Bp_%7Bback%7D%7D+-+p_%7Bfore%7D+%3D+k+%5C%5C+++%26+p_%7Bfore%7D%5E2+-+p_%7Bfore%7D+-+k%5Ccdot+p_%7Bback%7D++%3D+0+%5C%5C+++%26+p_%7Bfore%7D+%3D+%5Cfrac%7B1%7D%7B2%7D+%5Cpm+%5Cfrac%7B%5Csqrt%7B1+%2B+4+%5Ccdot+k+%5Ccdot+p_%7Bback%7D%7D%7D%7B2%7D++%5Cend%7Baligned%7D++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  \begin{aligned}  JLH = &amp; \frac{p_{fore}^2}{p_{back}} - p_{fore} = k \\   &amp; p_{fore}^2 - p_{fore} - k\cdot p_{back}  = 0 \\   &amp; p_{fore} = \frac{1}{2} \pm \frac{\sqrt{1 + 4 \cdot k \cdot p_{back}}}{2}  \end{aligned}  ' title='  \begin{aligned}  JLH = &amp; \frac{p_{fore}^2}{p_{back}} - p_{fore} = k \\   &amp; p_{fore}^2 - p_{fore} - k\cdot p_{back}  = 0 \\   &amp; p_{fore} = \frac{1}{2} \pm \frac{\sqrt{1 + 4 \cdot k \cdot p_{back}}}{2}  \end{aligned}  ' class='latex' />
<p>Where the negative part is outside of function definition area.<br />
This is far easier to see in the simplified formula.</p>
<img src='http://s0.wp.com/latex.php?latex=++%5Cbegin%7Baligned%7D++JLH+%3D+%26+%5Cfrac%7Bp_%7Bfore%7D%5E2%7D%7Bp_%7Bback%7D%7D+%3D+k+%5C%5C+++%26+p_%7Bfore%7D+%3D+%5Csqrt%7Bk+%5Ccdot+p_%7Bback%7D%7D++%5Cend%7Baligned%7D++&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='  \begin{aligned}  JLH = &amp; \frac{p_{fore}^2}{p_{back}} = k \\   &amp; p_{fore} = \sqrt{k \cdot p_{back}}  \end{aligned}  ' title='  \begin{aligned}  JLH = &amp; \frac{p_{fore}^2}{p_{back}} = k \\   &amp; p_{fore} = \sqrt{k \cdot p_{back}}  \end{aligned}  ' class='latex' />
<p>An increase in <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> must be offset by approximately a square root increase in <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> to  retain the same score.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/06/JLH-contour.png"><img src="http://blog.comperiosearch.com/wp-content/uploads/2015/06/JLH-contour-300x209.png" alt="JLH-contour" width="300" height="209" class="alignnone size-medium wp-image-3791"></a></p>
<p>As we see the score increases sharply as <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> increases in a quadratic manner against <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' />. As <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> becomes small compared to <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> the growth goes from linear in <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> to squared.</p>
<p>Finally a 3D plot of the score function.</p>
<p><a href="http://blog.comperiosearch.com/wp-content/uploads/2015/06/JLH-3d.png"><img src="http://blog.comperiosearch.com/wp-content/uploads/2015/06/JLH-3d-300x203.png" alt="JLH-3d" width="300" height="203" class="alignnone size-medium wp-image-3790"></a></p>
<p>So what can we take away from all this? I think the main practical consideration is the squared relationship between <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> and <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> which means once there is significant difference between the two the <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> will dominate the score ranking. The <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> factor primarily makes the score sensitive when this factor is small and for reasonable similar <img src='http://s0.wp.com/latex.php?latex=p_%7Bback%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{back}' title='p_{back}' class='latex' /> the <img src='http://s0.wp.com/latex.php?latex=p_%7Bfore%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='p_{fore}' title='p_{fore}' class='latex' /> decides the ranking. There are some obvious consequences from this which would be interesting to explore in real data. First that you would like to have a large background document set if you want more fine grained sensitivity to background frequency. Second, foreground frequencies can dominate the score to such an extent that peculiarities of the implementation may show up in the significant terms ranking, which we will look at in more detail as we try to apply the significant terms aggregation to single documents.</p>
<p>The results and visualizations in this blog post is also available as an <a href="https://github.com/andrely/ipython-notebooks/blob/master/JLH%20score%20characteristics.ipynb" title="JLH score characteristics">iPython notebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.comperiosearch.com/blog/2015/06/10/how-elasticsearch-calculates-significant-terms/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
