<?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>Sitecore Fetch Squad</title>
	<atom:link href="http://squad.jpkeisala.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://squad.jpkeisala.com</link>
	<description>Automated crawler fetching websites and blogs from Sitecore content</description>
	<lastBuildDate>Sun, 30 Oct 2011 09:13:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Sitecore Lucene index does not remove old data</title>
		<link>http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/</link>
		<comments>http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/</guid>
		<description><![CDATA[Looks like interest to Sitecore implementation of Lucene index has raised since Dream Core event and developers have run into an issue with old data being kept in the index repository. In this article I want to show you how to go around this issue.First of all let’s see why it’s happening. I ran into [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">
<p>Looks like interest to Sitecore implementation of Lucene index has raised since <a href="http://dreamcore.sitecore.net/" target="_blank">Dream Core</a> event and developers have run into an issue with old data being kept in the index repository. In this article I want to show you how to go around this issue.<br />First of all let’s see why it’s happening. I ran into this issue when I started playing with new implementation of Lucene index in Sitecore 6. When I created an output of the results I saw duplicates of my data in there. I stated debugging my code and found that Lucene somehow recognizes raw GUID’s which breaks search criteria that Sitecore uses to find items during update/delete procedure. <br />To solve this issue I had to create additional field for Lucene index (_shorttemplateid) and store there short GUID for an item (item.ID.ToShortID()). Then override AddMatchCriteria method and dependent properties to use short template GUID for matching criteria. Below is the code example.</p>
<p>
<div>
<div>
<div>Code Snippet</div>
<div>
<ol>
<li><span>namespace</span> LuceneExamples</li>
<li>{</li>
<li>   <span>public</span> <span>class</span> <span>DatabaseCrawler</span> : Sitecore.Search.Crawlers.<span>DatabaseCrawler</span></li>
<li>   {</li>
<li>      <span>#region</span> Fields</li>
<li>&nbsp;</li>
<li>      <span>private</span> <span>bool</span> _hasIncludes;</li>
<li>      <span>private</span> <span>bool</span> _hasExcludes;</li>
<li>      <span>private</span> <span>Dictionary</span>&lt;<span>string</span>, <span>bool</span>&gt; _templateFilter;</li>
<li>      <span>private</span> <span>ArrayList</span> _customFields;</li>
<li>&nbsp;</li>
<li>      <span>#endregion</span> Fields</li>
<li>&nbsp;</li>
<li>      <span>#region</span> ctor</li>
<li>&nbsp;</li>
<li>      <span>public</span> DatabaseCrawler()</li>
<li>      {</li>
<li>         _templateFilter = <span>new</span> <span>Dictionary</span>&lt;<span>string</span>, <span>bool</span>&gt;();</li>
<li>         _customFields = <span>new</span> <span>ArrayList</span>();</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>#endregion</span> ctor</li>
<li>&nbsp;</li>
<li>      <span>#region</span> Base class methods</li>
<li>&nbsp;</li>
<li>      <span>// Should be overriden to add date fields in &quot;yyyyMMddHHmmss&quot; format. Otherwise it&#39;s not possible to create range queries for date values.</span></li>
<li>      <span>// Also adds _shorttemplateid field which has a template id in ShortID format.</span></li>
<li>      <span>protected</span> <span>override</span> <span>void</span> AddAllFields(<span>Document</span> document, <span>Item</span> item, <span>bool</span> versionSpecific)</li>
<li>      {</li>
<li>         <span>Assert</span>.ArgumentNotNull(document, <span>&quot;document&quot;</span>);</li>
<li>         <span>Assert</span>.ArgumentNotNull(item, <span>&quot;item&quot;</span>);</li>
<li>         Sitecore.Collections.<span>FieldCollection</span> fields = item.Fields;</li>
<li>         fields.ReadAll();</li>
<li>         <span>foreach</span> (Sitecore.Data.Fields.<span>Field</span> field <span>in</span> fields)</li>
<li>         {</li>
<li>            <span>if</span> (!<span>string</span>.IsNullOrEmpty(field.Key) &amp;&amp; (field.Shared != versionSpecific))</li>
<li>            {</li>
<li>               <span>bool</span> tokenize = <span>base</span>.IsTextField(field);</li>
<li>               <span>if</span> (IndexAllFields)</li>
<li>               {</li>
<li>                  <span>if</span> (field.TypeKey == <span>&quot;date&quot;</span> || field.TypeKey == <span>&quot;datetime&quot;</span>)</li>
<li>                  {</li>
<li>                     IndexDateFields(document, field.Key, field.Value);</li>
<li>                  }</li>
<li>                  <span>else</span></li>
<li>                  {</li>
<li>                     document.Add(CreateField(field.Key, field.Value, tokenize, 1f));</li>
<li>                  }</li>
<li>               }</li>
<li>               <span>if</span> (tokenize)</li>
<li>               {</li>
<li>                  document.Add(CreateField(<span>BuiltinFields</span>.Content, field.Value, <span>true</span>, 1f));</li>
<li>               }</li>
<li>            }</li>
<li>         }</li>
<li>         AddShortTemplateId(document, item);</li>
<li>         AddCustomFields(document, item);</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>///</span><span> </span><span>&lt;summary&gt;</span></li>
<li>      <span>///</span><span> Loops through the collection of custom fields and adds them to fields collection of each indexed item.</span></li>
<li>      <span>///</span><span> </span><span>&lt;/summary&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;document&quot;&gt;</span><span>Lucene document</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;item&quot;&gt;</span><span>Sitecore data item</span><span>&lt;/param&gt;</span></li>
<li>      <span>private</span> <span>void</span> AddCustomFields(<span>Document</span> document, <span>Item</span> item)</li>
<li>      {</li>
<li>         <span>foreach</span>(<span>CustomField</span> field <span>in</span> _customFields)</li>
<li>         {</li>
<li>            document.Add(CreateField(field.LuceneFieldName, field.GetFieldValue(item), field.StorageType, field.IndexType, Boost));</li>
<li>         }</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>///</span><span> </span><span>&lt;summary&gt;</span></li>
<li>      <span>///</span><span> Creates a Lucene field.</span></li>
<li>      <span>///</span><span> </span><span>&lt;/summary&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;fieldKey&quot;&gt;</span><span>Field name</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;fieldValue&quot;&gt;</span><span>Field value</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;storeType&quot;&gt;</span><span>Storage option</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;indexType&quot;&gt;</span><span>Index type</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;boost&quot;&gt;</span><span>Boosting parameter</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;returns&gt;&lt;/returns&gt;</span></li>
<li>      <span>private</span> <span>Fieldable</span> CreateField(<span>string</span> fieldKey, <span>string</span> fieldValue, <span>Field</span>.<span>Store</span> storeType, <span>Field</span>.<span>Index</span> indexType, <span>float</span> boost)</li>
<li>      {</li>
<li>         <span>Field</span> field = <span>new</span> <span>Field</span>(fieldKey, fieldValue, storeType, indexType);</li>
<li>         field.SetBoost(boost);</li>
<li>         <span>return</span> field;</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>///</span><span> </span><span>&lt;summary&gt;</span></li>
<li>      <span>///</span><span> Parses a configuration entry for a custom field and adds it to a collection of custom fields.</span></li>
<li>      <span>///</span><span> </span><span>&lt;/summary&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;node&quot;&gt;</span><span>Configuration entry</span><span>&lt;/param&gt;</span></li>
<li>      <span>public</span> <span>void</span> AddCustomField(<span>XmlNode</span> node)</li>
<li>      {</li>
<li>         <span>CustomField</span> field = <span>CustomField</span>.ParseConfigNode(node);</li>
<li>         <span>if</span> (field == <span>null</span>)</li>
<li>         {</li>
<li>            <span>throw</span> <span>new</span> <span>InvalidOperationException</span>(<span>&quot;Could not parse custom field entry: &quot;</span> + node.OuterXml);</li>
<li>         }</li>
<li>         _customFields.Add(field);</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>// Method should use _shorttemplateid to allow one create combined/boolean search queries with template id reference.</span></li>
<li>      <span>// Also used to create a matching criteria for update/delete actions.</span></li>
<li>      <span>protected</span> <span>override</span> <span>void</span> AddMatchCriteria(<span>BooleanQuery</span> query)</li>
<li>      {</li>
<li>         query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>BuiltinFields</span>.Database, Database)), <span>BooleanClause</span>.<span>Occur</span>.MUST);</li>
<li>         query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>BuiltinFields</span>.Path, Sitecore.Data.<span>ShortID</span>.Encode(Root).ToLowerInvariant())), <span>BooleanClause</span>.<span>Occur</span>.MUST);</li>
<li>         <span>if</span> (HasIncludes || HasExcludes)</li>
<li>         {</li>
<li>            <span>foreach</span> (<span>KeyValuePair</span>&lt;<span>string</span>, <span>bool</span>&gt; pair <span>in</span> TemplateFilter)</li>
<li>            {</li>
<li>               query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>Constants</span>.ShortTemplate, Sitecore.Data.<span>ShortID</span>.Encode(pair.Key).ToLowerInvariant())), pair.Value ? <span>BooleanClause</span>.<span>Occur</span>.SHOULD : <span>BooleanClause</span>.<span>Occur</span>.MUST_NOT);</li>
<li>            }</li>
<li>         }</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>// Method should be overriden because _hasIncludes and _hasExcludes variables were introduced.</span></li>
<li>      <span>protected</span> <span>override</span> <span>bool</span> IsMatch(<span>Item</span> item)</li>
<li>      {</li>
<li>          <span>bool</span> flag;</li>
<li>          <span>Assert</span>.ArgumentNotNull(item, <span>&quot;item&quot;</span>);</li>
<li>          <span>if</span> (!RootItem.Axes.IsAncestorOf(item))</li>
<li>          {</li>
<li>              <span>return</span> <span>false</span>;</li>
<li>          }</li>
<li>          <span>if</span> (!HasIncludes &amp;&amp; !HasExcludes)</li>
<li>          {</li>
<li>              <span>return</span> <span>true</span>;</li>
<li>          }</li>
<li>          <span>if</span> (!TemplateFilter.TryGetValue(item.TemplateID.ToString(), <span>out</span> flag))</li>
<li>          {</li>
<li>              <span>return</span> !HasIncludes;</li>
<li>          }</li>
<li>          <span>return</span> flag;</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>// Method required to override AddMatchCriteria one.</span></li>
<li>      <span>new</span> <span>public</span> <span>void</span> IncludeTemplate(<span>string</span> templateId)</li>
<li>      {</li>
<li>         <span>Assert</span>.ArgumentNotNullOrEmpty(templateId, <span>&quot;templateId&quot;</span>);</li>
<li>         _hasIncludes = <span>true</span>;</li>
<li>         _templateFilter[templateId] = <span>true</span>;</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>// Method required to override AddMatchCriteria one.</span></li>
<li>      <span>new</span> <span>public</span> <span>void</span> ExcludeTemplate(<span>string</span> templateId)</li>
<li>      {</li>
<li>         <span>Assert</span>.ArgumentNotNullOrEmpty(templateId, <span>&quot;templateId&quot;</span>);</li>
<li>         _hasExcludes = <span>true</span>;</li>
<li>         _templateFilter[templateId] = <span>false</span>;</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>#endregion</span> Base class methods</li>
<li>&nbsp;</li>
<li>      <span>///</span><span> </span><span>&lt;summary&gt;</span></li>
<li>      <span>///</span><span> Converts Sitecore date and datetime fields to the recognizable format for Lucene API.</span></li>
<li>      <span>///</span><span> </span><span>&lt;/summary&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;doc&quot;&gt;</span><span>Lucene document object</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;fieldKey&quot;&gt;</span><span>Field name</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;fieldValue&quot;&gt;</span><span>Field value</span><span>&lt;/param&gt;</span></li>
<li>      <span>private</span> <span>void</span> IndexDateFields(<span>Document</span> doc, <span>string</span> fieldKey, <span>string</span> fieldValue)</li>
<li>      {</li>
<li>         <span>DateTime</span> dateTime = Sitecore.<span>DateUtil</span>.IsoDateToDateTime(fieldValue);</li>
<li>         <span>string</span> luceneDate = <span>&quot;&quot;</span>;</li>
<li>         <span>if</span> (dateTime != <span>DateTime</span>.MinValue)</li>
<li>         {</li>
<li>            luceneDate = dateTime.ToString(<span>Constants</span>.DateTimeFormat);</li>
<li>         }</li>
<li>         doc.Add(CreateField(fieldKey, luceneDate, <span>false</span>, 1f));</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>///</span><span> </span><span>&lt;summary&gt;</span></li>
<li>      <span>///</span><span> Adds template id in ShortID format</span></li>
<li>      <span>///</span><span> </span><span>&lt;/summary&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;doc&quot;&gt;</span><span>Lucene document object</span><span>&lt;/param&gt;</span></li>
<li>      <span>///</span><span> </span><span>&lt;param name=&quot;item&quot;&gt;</span><span>Sitecore item</span><span>&lt;/param&gt;</span></li>
<li>      <span>private</span> <span>void</span> AddShortTemplateId(<span>Document</span> doc, <span>Item</span> item)</li>
<li>      {</li>
<li>         doc.Add(CreateField(<span>Constants</span>.ShortTemplate, Sitecore.Data.<span>ShortID</span>.Encode(item.TemplateID).ToLowerInvariant(), <span>false</span>, 1f));</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>#region</span> Properties</li>
<li>&nbsp;</li>
<li>      <span>protected</span> <span>bool</span> HasIncludes</li>
<li>      {</li>
<li>         <span>get</span></li>
<li>         {</li>
<li>            <span>return</span> _hasIncludes;</li>
<li>         }</li>
<li>         <span>set</span></li>
<li>         {</li>
<li>            _hasIncludes = <span>value</span>;</li>
<li>         }</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>protected</span> <span>bool</span> HasExcludes</li>
<li>      {</li>
<li>         <span>get</span></li>
<li>         {</li>
<li>            <span>return</span> _hasExcludes;</li>
<li>         }</li>
<li>         <span>set</span></li>
<li>         {</li>
<li>            _hasExcludes = <span>value</span>;</li>
<li>         }</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>protected</span> <span>Dictionary</span>&lt;<span>string</span>, <span>bool</span>&gt; TemplateFilter</li>
<li>      {</li>
<li>         <span>get</span></li>
<li>         {</li>
<li>            <span>return</span> _templateFilter;</li>
<li>         }</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>protected</span> <span>Item</span> RootItem</li>
<li>      {</li>
<li>         <span>get</span></li>
<li>         {</li>
<li>            <span>return</span> Sitecore.Data.Managers.<span>ItemManager</span>.GetItem(Root, Sitecore.Globalization.<span>Language</span>.Invariant,</li>
<li>                                                              Sitecore.Data.<span>Version</span>.Latest,</li>
<li>                                                              Sitecore.Data.<span>Database</span>.GetDatabase(Database),</li>
<li>                                                              Sitecore.SecurityModel.<span>SecurityCheck</span>.Disable);</li>
<li>         }</li>
<li>      }</li>
<li>&nbsp;</li>
<li>      <span>#endregion</span> Properties</li>
<li>&nbsp;</li>
<li>   }</li>
<li>}</li>
</ol></div>
</p></div>
</p></div>
</p>
<p>This should solve this issue as well as add Lucene recognizable format for Sitecore date and datetime field types. Also it will allow to build Combined and Boolean search queries.</p>
<p>Update. Code for the Constants class:</p>
<p>
<div>
<div>
<pre><span>   1:</span> <span>namespace</span> LuceneExamples</pre>
<p><!--CRLF-->
<pre><span>   2:</span> {</pre>
<p><!--CRLF-->
<pre><span>   3:</span>    <span>public</span> <span>class</span> Constants</pre>
<p><!--CRLF-->
<pre><span>   4:</span>    {</pre>
<p><!--CRLF-->
<pre><span>   5:</span>       <span>// special field for template id in ShortID format</span></pre>
<p><!--CRLF-->
<pre><span>   6:</span>       <span>public</span> <span>const</span> <span>string</span> ShortTemplate = <span>"_shorttemplateid"</span>;</pre>
<p><!--CRLF-->
<pre><span>   7:</span>&nbsp; </pre>
<p><!--CRLF-->
<pre><span>   8:</span>       <span>// searchable date-time format. All datetime field</span></pre>
<p><!--CRLF-->
<pre><span>   9:</span>       <span>public</span> <span>const</span> <span>string</span> DateTimeFormat = <span>"yyyyMMddHHmmss"</span>;</pre>
<p><!--CRLF-->
<pre><span>  10:</span>&nbsp; </pre>
<p><!--CRLF-->
<pre><span>  11:</span>       <span>// Path to lucene setting items: /sitecore/system/Settings/Lucene</span></pre>
<p><!--CRLF-->
<pre><span>  12:</span>       <span>public</span> <span>const</span> <span>string</span> LuceneSettingsPath = <span>"{89783047-026C-45B5-AB5B-338E4A22446C}"</span>;</pre>
<p><!--CRLF-->
<pre><span>  13:</span>    }</pre>
<p><!--CRLF-->
<pre><span>  14:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>Hope it saves someone a minute or two.</p>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/57757_5251195438749660493-8670509970573191107?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html">http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/&amp;title=Sitecore Lucene index does not remove old data">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/sitecore-lucene-index-does-not-remove-old-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remove old data form the index for Sitecore 6.2 (Update-4) and 6.3</title>
		<link>http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/</link>
		<comments>http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/</guid>
		<description><![CDATA[Previously I published an article explaining how to fix a glitch in Sitecore index that keeps old data after updating an item. In this article I updated the code since some issues were fixed in Sitecore 6.2 (Update-4) and 6.3. Starting from 6.2 (Update-4) and 6.3 the _template field in Lucene index stores an item [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">
<p>Previously I published <a href="http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html">an article</a> explaining how to fix a glitch in Sitecore index that keeps old data after updating an item. In this article I updated the code since some issues were fixed in Sitecore 6.2 (Update-4) and 6.3.</p>
<p>Starting from 6.2 (Update-4) and 6.3 the _template field in Lucene index stores an item ID in ShortID format. Now it’s even easier to customize the DatabaseCrawler as the following methods were made virtual: AddItem, IndexVersion, DeleteItem and DeleteVersion. Also fields _hasIncludes, _hasExludes and _templateFilder were made protected which helps to shrink the fix even more.</p>
<p>Here is the code that fixes the outlined problem for these releases:</p>
<div>
<div>
<div>Code Snippet</div>
<div>
<ol>
<li><span>namespace</span> Lucene.Search.Crawlers</li>
<li>{</li>
<li>    <span>public</span> <span>class</span> <span>DatabaseCrawler</span> : Sitecore.Search.Crawlers.<span>DatabaseCrawler</span></li>
<li>    {</li>
<li>        <span>protected</span> <span>override</span> <span>void</span> AddMatchCriteria(Net.Search.<span>BooleanQuery</span> query)</li>
<li>        {</li>
<li>            query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>BuiltinFields</span>.Database, RootItem.Database.Name)), <span>BooleanClause</span>.<span>Occur</span>.MUST);</li>
<li>            query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>BuiltinFields</span>.Path, <span>ShortID</span>.Encode(RootItem.ID).ToLowerInvariant())), <span>BooleanClause</span>.<span>Occur</span>.MUST);</li>
<li>            <span>if</span> (<span>this</span>._hasIncludes || <span>this</span>._hasExcludes)</li>
<li>            {</li>
<li>                <span>foreach</span> (<span>KeyValuePair</span>&lt;<span>string</span>, <span>bool</span>&gt; pair <span>in</span> <span>this</span>._templateFilter)</li>
<li>                {</li>
<li>                    query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>BuiltinFields</span>.Template, <span>ShortID</span>.Encode(pair.Key).ToLowerInvariant())), pair.Value ? <span>BooleanClause</span>.<span>Occur</span>.SHOULD : <span>BooleanClause</span>.<span>Occur</span>.MUST_NOT);</li>
<li>                }</li>
<li>            }</li>
<li>        }</li>
<li>&nbsp;</li>
<li>        <span>protected</span> <span>Item</span> RootItem</li>
<li>        {</li>
<li>            <span>get</span></li>
<li>            {</li>
<li>                <span>return</span> Sitecore.Data.Managers.<span>ItemManager</span>.GetItem(Root, Sitecore.Globalization.<span>Language</span>.Invariant,</li>
<li>                                                                  Sitecore.Data.<span>Version</span>.Latest,</li>
<li>                                                                  Sitecore.Data.<span>Database</span>.GetDatabase(Database),</li>
<li>                                                                  Sitecore.SecurityModel.<span>SecurityCheck</span>.Disable);</li>
<li>            }</li>
<li>        }</li>
<li>&nbsp;</li>
<li>        <span>protected</span> <span>override</span> <span>Query</span> GetVersionQuery(<span>ID</span> id, <span>string</span> language, <span>string</span> version)</li>
<li>        {</li>
<li>            <span>Assert</span>.ArgumentNotNull(id, <span>&quot;id&quot;</span>);</li>
<li>            <span>Assert</span>.ArgumentNotNullOrEmpty(language, <span>&quot;language&quot;</span>);</li>
<li>            <span>Assert</span>.ArgumentNotNullOrEmpty(version, <span>&quot;version&quot;</span>);</li>
<li>            <span>BooleanQuery</span> query = <span>new</span> <span>BooleanQuery</span>();</li>
<li>            query.Add(<span>new</span> <span>TermQuery</span>(<span>new</span> <span>Term</span>(<span>BuiltinFields</span>.ID, GetItemID(id, language, version).ToLowerInvariant())), <span>BooleanClause</span>.<span>Occur</span>.MUST);</li>
<li>            <span>this</span>.AddMatchCriteria(query);</li>
<li>            <span>return</span> query;</li>
<li>        }</li>
<li>    }</li>
<li>}</li>
</ol></div>
</p></div>
</p></div>
<p>Basically you need to make sure that the result of GetItemID method is in lower case as well as a term for _path field, in AddMatchCriteria method, is constructed with lower case query.</p>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/57757_5251195438749660493-2315435169347766261?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2010/10/remove-old-data-form-index-for-sitecore.html">http://sitecoregadgets.blogspot.com/2010/10/remove-old-data-form-index-for-sitecore.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/&amp;title=Remove old data form the index for Sitecore 6.2 (Update-4) and 6.3">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/remove-old-data-form-the-index-for-sitecore-6-2-update-4-and-6-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding custom fields to the index</title>
		<link>http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/</link>
		<comments>http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/</guid>
		<description><![CDATA[In this post I want to show how to address a missing feature that was a part of “old” lucene index implementation. This article will provide an example how one can customize Lucene search configuration so that it’s possible to add custom fields to the index. First off, let’s create a configuration that would allow [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">
<p>In this post I want to show how to address a missing feature that was a part of “old” lucene index implementation. This article will provide an example how one can customize Lucene search configuration so that it’s possible to add custom fields to the index.</p>
<p>First off, let’s create a configuration that would allow us to add additional fields to the indexed data.</p>
<pre><span>&lt;</span><span>index </span><span>id</span><span>=</span>&quot;<span>News</span>&quot; <span>type</span><span>=</span>&quot;<span>Sitecore.Search.Index, Sitecore.Kernel</span>&quot;<span>&gt;  &lt;</span><span>param </span><span>desc</span><span>=</span>&quot;<span>name</span>&quot;<span>&gt;</span>$(id)<span>&lt;/</span><span>param</span><span>&gt;  &lt;</span><span>param </span><span>desc</span><span>=</span>&quot;<span>folder</span>&quot;<span>&gt;_</span>news<span>&lt;/</span><span>param</span><span>&gt;  &lt;</span><span>Analyzer </span><span>ref</span><span>=</span>&quot;<span>search/analyzer</span>&quot; <span>/&gt;  &lt;</span><span>locations </span><span>hint</span><span>=</span>&quot;<span>list:AddCrawler</span>&quot;<span>&gt;    &lt;</span><span>examples-news </span><span>type</span><span>=</span>&quot;<span>LuceneExamples.DatabaseCrawler,LuceneExamples</span>&quot;<span>&gt;      &lt;</span><span>Database</span><span>&gt;</span>web<span>&lt;/</span><span>Database</span><span>&gt;      &lt;</span><span>Root</span><span>&gt;</span>/sitecore/content<span>&lt;/</span><span>Root</span><span>&gt;      &lt;</span><span>IndexAllFields</span><span>&gt;</span>true<span>&lt;/</span><span>IndexAllFields</span><span>&gt;      &lt;</span><span>include </span><span>hint</span><span>=</span>&quot;<span>list:IncludeTemplate</span>&quot;<span>&gt;        &lt;</span><span>news</span><span>&gt;</span>{788EF1BE-B71E-4D59-9276-50519BD4F641}<span>&lt;/</span><span>news</span><span>&gt;        &lt;</span><span>tag</span><span>&gt;</span>{4DD970FB-2695-4E50-96F3-A766F7D6CAF1}<span>&lt;/</span><span>tag</span><span>&gt;      &lt;/</span><span>include</span><span>&gt;      &lt;</span><span>fields </span><span>hint</span><span>=</span>&quot;<span>raw:AddCustomField</span>&quot;<span>&gt;        &lt;</span><span>field </span><span>luceneName</span><span>=</span>&quot;<span>author</span>&quot; <span>storageType</span><span>=</span>&quot;<span>no</span>&quot; <span>indexType</span><span>=</span>&quot;<span>tokenized</span>&quot;<span>&gt;</span>__updated by<span>&lt;/</span><span>field</span><span>&gt;        &lt;</span><span>field </span><span>luceneName</span><span>=</span>&quot;<span>changed</span>&quot; <span>storageType</span><span>=</span>&quot;<span>yes</span>&quot; <span>indexType</span><span>=</span>&quot;<span>untokenized</span>&quot;<span>&gt;</span>__updated<span>&lt;/</span><span>field</span><span>&gt;      &lt;/</span><span>fields</span><span>&gt;    &lt;/</span><span>examples-news</span><span>&gt;  &lt;/</span><span>locations</span><span>&gt;&lt;/</span><span>index</span><span>&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a>
<p>There is a new configuration section in this example. It’s &lt;fields&gt; section that introduces two fields “author” and “changed”. These fields will be added to a fields collection of each indexed item. Basically, there is <strong>AddCustomField</strong> method that gets called for every &lt;field&gt; configuration entry to identify a custom field that is going to be added to the fields collection.</p>
<p>
<p>Description of configuration attributes:</p>
<p>
<ul>
<li>luceneName&#160; is a field name that appears in lucene index.</li>
<li>storageType&#160; is a storage type for lucene field. It can have the following values:
<ul>
<li>no</li>
<li>yes </li>
<li>compress</li>
</ul>
</li>
<li>indexType&#160; is an index type for lucene field. It can have the following values:
<ul>
<li>no </li>
<li>tokenized </li>
<li>untokenized </li>
<li>nonorms </li>
</ul>
</li>
</ul>
<p>
<p>Refere to Lucene documentation to find out what each of these options mean: <a href="http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/document/Field.Store.html" target="_blank">store</a> and <a href="http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/document/Field.Index.html" target="_blank">index</a>.</p>
<p>
<p>Now all you need to do is to loop through the collection of custom fields in the overridden <strong>AddAllFields</strong> method and add them to the indexed data.</p>
<p>
<p>I created a custom class called CustomField that helps to manage custom field entries. Below is the example of this class as well as additional methods for extended DatabaseCrawler. Since code for the DatabaseCrawler was already published in <a href="http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html" target="_blank">this blog post</a>, I’m not going to duplicate it here.</p>
<p>
<p>Here is a code for CustomField class.</p>
<p>
<pre><span>using </span>System.Xml;<span>using </span>Sitecore.Data;<span>using </span>Sitecore.Data.Items;<span>using </span>Sitecore.Xml;<span>using </span>Lucene.Net.Documents;

<span>namespace </span>LuceneExamples{   <span>public class </span><span>CustomField   </span>{      <span>public </span>CustomField()      {         FieldID = <span>ID</span>.Null;         FieldName = <span>&quot;&quot;</span>;         LuceneFieldName = <span>&quot;&quot;</span>;      }

      <span>public </span><span>ID </span>FieldID      {         <span>get</span>;         <span>private set</span>;      }

      <span>public string </span>FieldName { <span>get</span>; <span>private set</span>; }

      <span>public </span><span>Field</span>.<span>Store </span>StorageType { <span>get</span>; <span>set</span>; }

      <span>public </span><span>Field</span>.<span>Index </span>IndexType { <span>get</span>; <span>set</span>; }

      <span>public string </span>LuceneFieldName { <span>get</span>; <span>private set</span>; }

      <span>public static </span><span>CustomField </span>ParseConfigNode(<span>XmlNode </span>node)      {         <span>CustomField </span>field = <span>new </span><span>CustomField</span>();         <span>string </span>fieldName = <span>XmlUtil</span>.GetValue(node);         <span>if </span>(<span>ID</span>.IsID(fieldName))         {            field.FieldID = <span>ID</span>.Parse(fieldName);         }         <span>else         </span>{            field.FieldName = fieldName;         }         field.LuceneFieldName = <span>XmlUtil</span>.GetAttribute(<span>&quot;luceneName&quot;</span>, node);         field.StorageType = GetStorageType(node);         field.IndexType = GetIndexType(node);

         <span>if </span>(!IsValidField(field))         {            <span>return null</span>;         }

         <span>return </span>field;      }

      <span>public string </span>GetFieldValue(<span>Item </span>item)      {         <span>if </span>(!<span>ID</span>.IsNullOrEmpty(FieldID))         {            <span>return </span>item[<span>ID</span>.Parse(FieldID)];         }         <span>if</span>(!<span>string</span>.IsNullOrEmpty(FieldName))         {            <span>return </span>item[FieldName];         }         <span>return string</span>.Empty;      }

      <span>private static bool </span>IsValidField(<span>CustomField </span>field)      {         <span>if </span>((!<span>string</span>.IsNullOrEmpty(field.FieldName) || !<span>ID</span>.IsNullOrEmpty(field.FieldID)) &amp;&amp; !<span>string</span>.IsNullOrEmpty(field.LuceneFieldName))         {            <span>return true</span>;         }         <span>return false</span>;      }

      <span>private static </span><span>Field</span>.<span>Index </span>GetIndexType(<span>XmlNode </span>node)      {         <span>string </span>indexType = <span>XmlUtil</span>.GetAttribute(<span>&quot;indexType&quot;</span>, node);         <span>if </span>(!<span>string</span>.IsNullOrEmpty(indexType))         {            <span>switch </span>(indexType.ToLowerInvariant())            {               <span>case </span><span>&quot;no&quot;</span>:                  <span>return </span><span>Field</span>.<span>Index</span>.NO;               <span>case </span><span>&quot;tokenized&quot;</span>:                  <span>return </span><span>Field</span>.<span>Index</span>.TOKENIZED;               <span>case </span><span>&quot;untokenized&quot;</span>:                  <span>return </span><span>Field</span>.<span>Index</span>.UN_TOKENIZED;               <span>case </span><span>&quot;nonorms&quot;</span>:                  <span>return </span><span>Field</span>.<span>Index</span>.NO_NORMS;            }         }         <span>return </span><span>Field</span>.<span>Index</span>.TOKENIZED;      }

      <span>private static </span><span>Field</span>.<span>Store </span>GetStorageType(<span>XmlNode </span>node)      {         <span>string </span>storage = <span>XmlUtil</span>.GetAttribute(<span>&quot;storageType&quot;</span>, node);         <span>if </span>(!<span>string</span>.IsNullOrEmpty(storage))         {            <span>switch </span>(storage.ToLowerInvariant())            {               <span>case </span><span>&quot;no&quot;</span>:                  <span>return </span><span>Field</span>.<span>Store</span>.NO;               <span>case </span><span>&quot;yes&quot;</span>:                  <span>return </span><span>Field</span>.<span>Store</span>.YES;               <span>case </span><span>&quot;compress&quot;</span>:                  <span>return </span><span>Field</span>.<span>Store</span>.COMPRESS;            }         }         <span>return </span><span>Field</span>.<span>Store</span>.NO;      }   }}</pre>
<p><a href="http://11011.net/software/vspaste"></a>
<p>And the code for additional methods for DatabaseCrawler.</p>
<p>
<pre><span>/// &lt;summary&gt;/// </span><span>Loops through the collection of custom fields and adds them to fields collection of each indexed item.</span><span>/// &lt;/summary&gt;/// &lt;param name=&quot;document&quot;&gt;</span><span>Lucene document</span><span>&lt;/param&gt;/// &lt;param name=&quot;item&quot;&gt;</span><span>Sitecore data item</span><span>&lt;/param&gt;</span><span>private void </span>AddCustomFields(<span>Document </span>document, <span>Item </span>item){   <span>foreach</span>(<span>CustomField </span>field <span>in </span>_customFields)   {      document.Add(CreateField(field.LuceneFieldName, field.GetFieldValue(item), field.StorageType, field.IndexType, Boost));   }}

<span>/// &lt;summary&gt;/// </span><span>Creates a Lucene field.</span><span>/// &lt;/summary&gt;/// &lt;param name=&quot;fieldKey&quot;&gt;</span><span>Field name</span><span>&lt;/param&gt;/// &lt;param name=&quot;fieldValue&quot;&gt;</span><span>Field value</span><span>&lt;/param&gt;/// &lt;param name=&quot;storeType&quot;&gt;</span><span>Storage option</span><span>&lt;/param&gt;/// &lt;param name=&quot;indexType&quot;&gt;</span><span>Index type</span><span>&lt;/param&gt;/// &lt;param name=&quot;boost&quot;&gt;</span><span>Boosting parameter</span><span>&lt;/param&gt;/// &lt;returns&gt;&lt;/returns&gt;</span><span>private </span><span>Fieldable </span>CreateField(<span>string </span>fieldKey, <span>string </span>fieldValue, <span>Field</span>.<span>Store </span>storeType, <span>Field</span>.<span>Index </span>indexType, <span>float </span>boost){   <span>Field </span>field = <span>new </span><span>Field</span>(fieldKey, fieldValue, storeType, indexType);   field.SetBoost(boost);   <span>return </span>field;}

<span>/// &lt;summary&gt;/// </span><span>Parses a configuration entry for a custom field and adds it to a collection of custom fields.</span><span>/// &lt;/summary&gt;/// &lt;param name=&quot;node&quot;&gt;</span><span>Configuration entry</span><span>&lt;/param&gt;</span><span>public void </span>AddCustomField(<span>XmlNode </span>node){   <span>CustomField </span>field = <span>CustomField</span>.ParseConfigNode(node);   <span>if </span>(field == <span>null</span>)   {      <span>throw new </span><span>InvalidOperationException</span>(<span>&quot;Could not parse custom field entry: &quot; </span>+ node.OuterXml);   }   _customFields.Add(field);}</pre>
<p>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>
<p>Last thing that is left to do is to call AddCustomFields method from AddAllFields one.</p>
<p>
<p><span>protected override void </span>AddAllFields (<span>Document</span>document, <span>Item</span>item, <span>bool </span>versionSpecific) <br /> {<br />   &#160;&#160;&#160; ………………………………………<br />   &#160;&#160;&#160; AddCustomFields(document, item); <br /> }</p>
<p>
<p>You can take it even further and add support for some field interpreter for each field configuration entry.</p>
<p>
<p>Hope you&#8217;ll find it useful.</p>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/e7e4a_5251195438749660493-1865361081035253937?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2010/08/adding-custom-fields-to-index.html">http://sitecoregadgets.blogspot.com/2010/08/adding-custom-fields-to-index.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/&amp;title=Adding custom fields to the index">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/adding-custom-fields-to-the-index/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Language filtered Multilist field</title>
		<link>http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/</link>
		<comments>http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/</guid>
		<description><![CDATA[Recently I happened to help one of our clients to create a custom Multilist field that gives you selecting options only if item has&#160; at least one translated version in a current content language. From content author’s point of view it makes a lot of sense. Why to give them an option that is not [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">
<p>Recently I happened to help one of our clients to create a custom Multilist field that gives you selecting options only if item has&#160; at least one translated version in a current content language. From content author’s point of view it makes a lot of sense. Why to give them an option that is not useful?</p>
<p>It’s being a while since I created a custom field that has to take into account content language selection. The main challenge for me was to retrieve that content language. I did remember that there is a property that the Content Editor (CE) sets at run-time for every field but could not recall its name. So after several minutes of browsing my code storage of all samples for all Sitecore versions, I finally found it. So, here are the properties that you need to define in your custom field if you are planning to use them afterwards:</p>
<p>- ItemLanauage – represents a content language selected in the CE.</p>
<p>- ItemID – contains the item ID the field belongs to.</p>
<p>- ItemVersion – contains selected item version.</p>
<p>- ReadOnly – indicates if field is a readonly. If it is, then it will be grayed out and not editable.</p>
<p>- Source – represents the source value from field definition on a data template.</p>
<p>- FieldID – contains the field ID.</p>
<p>In my example I needed only ItemLanguage property. When I put things together the code looked like this:</p>
<pre><span>using </span>Sitecore.Shell.Applications.ContentEditor;<span>using </span>Sitecore.Data.Items;

<span>namespace </span>Sitecore.Shell.Applications.ContentEditor.CustomExtensions{    <span>public class </span><span>LanguageFilteredMultilist </span>: Sitecore.Shell.Applications.ContentEditor.<span>MultilistEx    </span>{        <span>#region </span>Overrides

        <span>protected override </span><span>Item</span>[] GetItems(<span>Item </span>current)        {                          <span>Item</span>[] items = <span>base</span>.GetItems(current);

            <span>var </span>filteredItems = items.Where(item =&gt;                     {                        <span>string </span>lang = ItemLanguage;                        <span>if </span>(!<span>string</span>.IsNullOrEmpty(lang))                        {                            <span>var </span>versions = Sitecore.Data.Managers.<span>ItemManager</span>.GetVersions(item, Sitecore.Data.Managers.<span>LanguageManager</span>.GetLanguage(lang, item.Database));                            <span>return </span>versions.Count &gt; 0;                        }                        <span>return false</span>;                    }                );   

            <span>return </span>filteredItems.ToArray&lt;<span>Item</span>&gt;();        }

        <span>#endregion </span>Overrides

        <span>// Content Editor sets this property. It has a content language from the Content Editor.        </span><span>public string </span>ItemLanguage        {            <span>get</span>;            <span>set</span>;        }    }}</pre>
<p>Simple enough isn’t it. Don’t forget to add your custom field to /App_Config/FieldTypes.config file if it’s supposed to contain references to other items. In my case it should be added since it’s a multilist. If you forget to do it, the LinkDatabase won’t update references for your field.</p>
<p>That’s all for now.</p>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/e7e4a_5251195438749660493-5053570793654827073?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2010/08/language-filtered-multilist-field.html">http://sitecoregadgets.blogspot.com/2010/08/language-filtered-multilist-field.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/&amp;title=Language filtered Multilist field">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/language-filtered-multilist-field/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Teach User Manager how to search by email</title>
		<link>http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/</link>
		<comments>http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/</guid>
		<description><![CDATA[A couple of days ago one interesting issue popped out in my Inbox. Our customer wanted to search users by email address in User Manager application. Quite legitimate request. Especially if you have an integration with AD or CRM or whatever external security system with large number of users. I tried a couple of configuration [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">A couple of days ago one interesting issue popped out in my Inbox. Our customer wanted to search users by email address in User Manager application. Quite legitimate request. Especially if you have an integration with AD or CRM or whatever external security system with large number of users. I tried a couple of configuration changes with no luck. Then checked our support portal knowledge base and saw several request like that. I was surprised by the fact that you cannot search users by email.
<div>After spending several hours investigating how search functionality in User Manager works and doing some &#8220;shaman dancing&#8221; around it, I ended up with a solution that requires to override a standard Sitecore.Security.Accounts.UserProvider and change its method called &#8220;GetUsersByName&#8221;. As it turned out, search functionality of User Manager calls the GetUserByName method when one searches for a user.</div>
<div>This is how it looks:</div>
<div></div>
<div>
<div><span>namespace Sitecore.SharedSource.Security.Accounts</span></div>
<div><span>{</span></div>
<div><span>    public class UserProvider : Sitecore.Security.Accounts.UserProvider</span></div>
<div><span>    {</span></div>
<div><span>        protected override IEnumerable<user> GetUsersByName(int pageIndex, int pageSize, string userNameToMatch)</user></span></div>
<div><span>        {</span></div>
<div><span>            return FindUsers(pageIndex, pageSize, userNameToMatch);</span></div>
<div><span>        }</span></div>
<div><span><br /></span></div>
<div><span>        protected IEnumerable<user> FindUsers(int pageIndex, int pageSize, string userNameToMatch)</user></span></div>
<div><span>        {</span></div>
<div><span>            Assert.ArgumentNotNull(userNameToMatch, &#8220;userNameToMatch&#8221;);</span></div>
<div><span>            IEnumerable<user> users = null;</user></span></div>
<div><span>            string userWithNoWildcard = StringUtil.RemovePostfix(Settings.Authentication.VirtualMembershipWildcard, StringUtil.RemovePrefix(Settings.Authentication.VirtualMembershipWildcard, userNameToMatch));</span></div>
<div><span><br /></span></div>
<div><span>            if (Regex.IsMatch(userWithNoWildcard, @&#8221;^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$&#8221;))</span></div>
<div><span>            {</span></div>
<div><span>                users = findByEmail(pageIndex, pageSize, userWithNoWildcard);</span></div>
<div><span>            }</span></div>
<div><span>            else</span></div>
<div><span>            {</span></div>
<div><span>                users = findUsername(pageIndex, pageSize, userNameToMatch);</span></div>
<div><span>            }</span></div>
<div><span>            return users;</span></div>
<div><span>        }</span></div>
<div><span><br /></span></div>
<div><span>        protected IEnumerable<user> findUsername(int pageIndex, int pageSize, string username)</user></span></div>
<div><span>        {</span></div>
<div><span>            int total;</span></div>
<div><span>            return new Enumerable<user>(delegate</user></span></div>
<div><span>                {</span></div>
<div><span>                    return Membership.FindUsersByName(username, pageIndex, pageSize, out total).GetEnumerator();</span></div>
<div><span>                },</span></div>
<div><span>                delegate(object user)</span></div>
<div><span>                {</span></div>
<div><span>                    return User.FromName(((MembershipUser)user).UserName, false);</span></div>
<div><span>                });</span></div>
<div><span>        }</span></div>
<div><span><br /></span></div>
<div><span>        protected IEnumerable<user> findByEmail(int pageIndex, int pageSize, string userToMatch)</user></span></div>
<div><span>        {</span></div>
<div><span>            int total;</span></div>
<div><span>            return new Enumerable<user>(delegate</user></span></div>
<div><span>                {</span></div>
<div><span>                    return Membership.FindUsersByEmail(userToMatch, pageIndex, pageSize, out total).GetEnumerator();</span></div>
<div><span>                },</span></div>
<div><span>                delegate(object user)</span></div>
<div><span>                {</span></div>
<div><span>                    return User.FromName(((MembershipUser)user).UserName, false);</span></div>
<div><span>                });</span></div>
<div><span>        }</span></div>
<div><span>    }</span></div>
<div><span>}</span></div>
</div>
<div></div>
<div>That&#8217;s it! Simple enough, isn&#8217;t it.</div>
<div>Thanks to <a href="http://sitecoreblog.alexshyba.com/">Alex Shyba</a> who helped me with some useful code!</div>
<div></div>
<div>After compiling the code and moving a dll to the /bin folder, don&#8217;t forget to change a reference in web.config file to point it to a new UserProvider class.</p>
<p>&nbsp;&nbsp; &nbsp;&lt;userManager defaultProvider=&#8221;default&#8221; enabled=&#8221;true&#8221;&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp;&lt;providers&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;clear /&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;add name=&#8221;default&#8221;&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;x:attribute name=&#8221;type&#8221;&gt;Sitecore.SharedSource.Security.Accounts.UserProvider, <span>YOUR_DLL_HERE</span>&lt;/x:attribute&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;/add&gt;<br />&nbsp;&nbsp; &nbsp; &nbsp;&lt;/providers&gt;<br />&nbsp;&nbsp; &nbsp;&lt;/userManager&gt;
<div></div>
</div>
<div>For those who consider this so easy so that it&#8217;s now worth to create a VS project I&#8217;ve built a ready-to-go Sitecore package with a dll and include file inside. Just install it and give it a try <img src='http://squad.jpkeisala.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</div>
<div>This is a <a href="http://scusainc.com/SupportResources/ivan/Security/UserProvider/UserManager2-1.0.0.zip">Sitecore package</a>.</div>
<div></div>
<div>Enjoy!</div>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/e7e4a_5251195438749660493-791820903619949352?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2010/07/teach-user-manager-how-to-search-by.html">http://sitecoregadgets.blogspot.com/2010/07/teach-user-manager-how-to-search-by.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/&amp;title=Teach User Manager how to search by email">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/teach-user-manager-how-to-search-by-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with Lucene Search Index in Sitecore 6. Part III &#8211; Code examples</title>
		<link>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/</link>
		<comments>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/</guid>
		<description><![CDATA[If you read my previous posts about Lucene search index, then you already know how to configure it and how it works in Sitecore application. In this part we will take a look at API to see what can be achieved using the search index. To search existing index we need to get an index [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">
<div>If you read my previous posts about Lucene search index, then you already know how to configure it and how it works in Sitecore application.</div>
<div>In this part we will take a look at API to see what can be achieved using the search index.</div>
<div></div>
<div>To search existing index we need to get an index instance somehow. I&#8217;m not going to show the code examples that you would write with old search index. If you&#8217;re intrested in it, check out this article <a href="http://sdn.sitecore.net/Articles/Administration/Lucene%20Search%20Engine.aspx">Lecene Search Engine</a>.</div>
<div>Additional layer of API for new search index resides under <span>Sitecore.Search</span> namespace. In order to get a search index object, you would need to use members of SearchManager class.</div>
<div>To get an index by name use this line of code:</div>
<div><span> </span><span>Index indx = Search.Manager.GetIndex(index_name);</span></div>
<div>If you want to use default system index, you can simply call <span>SystemIndex</span> property of <span>SearchManager</span> class. In order to use Sitecore API to look up for some info in the index, you need to created a search context.</div>
<div>It&#8217;s easy to do by calling <span>CreateSearchContext</span> method of the index object we got previously. It&#8217;s also possible to create a search context by using one for the constructors of <span>IndexSearchContext</span> class. In this case it will be easy to run search queries by passing a search index instance as a parameter to the search context.</div>
<div>To search information, we need to create a query and run it in the search context. Sitecore API has a few classes that you can use to build search queries. Let&#8217;s take a look at each of them:</div>
<div><span> </span><span>FullTextQuery</span> &#8211; this type of query searches the index by &#8220;_content&#8221; field. All information from text fields (such as &#8220;Single-Line Text&#8221;, &#8220;Rich Text&#8221;, &#8220;Multi-Line Text&#8221;, &#8220;text&#8221;, &#8220;rich text&#8221;, &#8220;html&#8221;, &#8220;memo&#8221;) is stored there. Data in this field are indexed and tokenized. Which means that the search operations running on these data are very efficient.</div>
<div><span> </span><span>FieldQuery</span> &#8211; this type of query allows you to search any field that was added to the index. By default database crawler adds all item fields to the index.</div>
<div><span> </span><span>CombinedQuery</span> &#8211; this type of query was designed to allow you create complex queries with additional conditions. For instance to find items which have specific work in title and belong to some category. When you add search queries to this type of query, you need to supply <span>QueryOccurance</span> parameter. It&#8217;s Enum type that has the following members:</div>
<div> &#8211; Must &#8211; it&#8217;s a logical AND operator in Lucene boolean query.</div>
<div> &#8211; MustNot &#8211; it&#8217;s a logical NOT operator in Lucene boolean query.</div>
<div> &#8211; Should &#8211; it&#8217;s a logical OR operation in Lucene boolean query.</div>
<div>You can read more about this operators in <a href="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html">Query Parser Syntax article</a>.</div>
<div></div>
<div>All of these query types are derived from <span>QueryBase</span> class.</div>
<div><span> </span></div>
<div>There is one thing left until we jump from the theory to some code samples. To run defined queries, you need to use one of <span>Search</span> methods of <span>IndexSearchContext</span> object.<span> </span></div>
<div>Now let&#8217;s create a couple of samples to see a real code that goes behind the theory.</div>
<div></div>
<div><b>Sample 1: Searching text fields.</b></div>
<div>// Next samples will skip lines with getting the index instance and creating the search context.</div>
<div>// Get an index object</div>
<div><span>Index indx = SearchManager.GetIndex(&#8220;my_index&#8221;);</span></div>
<div>// Create a search context</div>
<div><span>using (IndexSearchContext searchContext = indx.CreateSearchContext())</span></div>
<div><span>{</span></div>
<div><span>   // In following examples I will be using QueryBase class to create search queries.</span></div>
<div><span>   FullTextQuery ftQuery = new FullTextQuery(&#8220;welcome&#8221;);</span></div>
<div><span>   SearchHits results = searchContext.Search(ftQuery);</span></div>
<div><span>}</span></div>
<div></div>
<div><b>Sample 2: Searching item fields</b></div>
<div>Let&#8217;s say we want to find items classified by some category. There is a trick searching by GUIDs so let&#8217;s say our category is just a string name.</div>
<div>&#8230;..</div>
<div><span>   // FieldQuery ctor accepts two parambers. First is a field name. The other one is a value we&#8217;re looking for.</span></div>
<div><span>   QueryBase query = FieldQuery(&#8220;category&#8221;, &#8220;slr&#8221;);</span></div>
<div><span>   SearchHits results = searchContext.Search(query);</span></div>
<div>&#8230;..</div>
<div></div>
<div><b>Sample 3: Searching by multiple conditions</b></div>
<div>Turned out that your category parameter is not enough to get required results. You client is screaming that there are too many items and business users cannot find ones they are looking for (is there anything they can find?).</div>
<div>Obviously you have some additional fields that can help to find more strict results. Let&#8217;s say there is a rating field with values from 1 to 5.</div>
<div>That&#8217;s where CombinedQuery gets into the game.</div>
<div>&#8230;..</div>
<div>   // CombinedQuery object has Add method that should be used to add search queries to it. That&#8217;s why we cannot use base class variable here.</div>
<div><span>   CombinedQuery query = new CombinedQuery();</span></div>
<div><span>   QueryBase catQuery = new FieldQuery(&#8220;category&#8221;, &#8220;slr&#8221;);</span></div>
<div><span>   QueryBase ratQuery = new FieldQuery(&#8220;rating&#8221;, &#8220;5&#8243;);</span></div>
<div><span>   query.Add(catQuery, QueryOccurance.Must);</span></div>
<div><span>   query.Add(ratQuery, QueryOccurance.Must);</span></div>
<div><span>   var hits = searchContext.Search(query);</span></div>
<div>&#8230;..</div>
<div></div>
<div>All results are presented as <span>SearchHits</span> object. Now you should use of following methods of SearchHits object to get the results as Sitecore items:</div>
<div> &#8211; FetchResults(int, int) &#8211; returns search results as SearchResultCollection. First parameter is a start position of an item you want to start fetching results from. Second one is count of items you want to fetch. By calling this function as mentioned below, you can get all results at once:</div>
<div><span> </span><span>var results = hits.FetchResults(0, hits.Length);</span></div>
<div></div>
<div>- Slice(int) &#8211; returns all results as <span>IEnumerable<searchhit></searchhit></span> collection.</div>
<div></div>
<div>- Slice(int, int) &#8211; this method has similar signature to FetchResults but returns results as <span>IEnumerable<searchhit></searchhit></span> collection.</div>
<div></div>
<div>Here are a couple of examples the way you can transform SearchHits object into Sitecore items.</div>
<div><b>Sample 4: using FetchResults</b></div>
<div>  &#8230;..</div>
<div><span>  SearchResultCollection results = hits.FetchResults(0, hits.Length);</span></div>
<div><span>  IEnumerable<item> searchItems = from hit in results</item></span></div>
<div><span>                                                                   select hit.GetObject<item>();</item></span></div>
<div><span>  }</span></div>
<div>  &#8230;..</div>
<div></div>
<div><b>Sample 5: using Slice</b></div>
<div>  &#8230;..</div>
<div><span>  IList<item> searchItems = List<item>();</item></item></span></div>
<div><span>  foreach(var hit in hits.Slice(0))</span></div>
<div><span>  {</span></div>
<div><span>     ItemUri itemUri = new ItemUri(hit.Url);</span></div>
<div><span>     if (itemUri != null)</span></div>
<div><span>     {</span></div>
<div><span>        Item item = ItemManager.GetItem(itemUri.ItemID, itemUri.Language, itemUri.Version, Factory.GetDatabase(itemUri.DatabaseName));</span></div>
<div><span>        if (item != null)</span></div>
<div><span>        {</span></div>
<div><span>           searchItems.Add(item);</span></div>
<div><span>        }</span></div>
<div><span>     }</span></div>
<div><span>  }</span></div>
<div>  &#8230;..</div>
<div></div>
<div>It&#8217;s worth to mention that some variations of Search method of IndexSearchContext class can accept Lucene.Net.Search.Query as a search query parameter. It becomes very useful when you need to create a complex query which cannot be built with Sitecore query types.</div>
<div></div>
<div><b>Searching GUIDs</b>.</div>
<div></div>
<div>New search index has lots of useful built-in fields that help to build strict queries.</div>
<div>Besides standard fields it has the following fields that contain GUIDs in ShortID format:</div>
<div> &#8211; _links &#8211; contains all references to current item</div>
<div></div>
<div> &#8211; _path &#8211; contains ShortIDs for every parent item in the path relative to current item</div>
<div></div>
<div> &#8211; _template &#8211; contains GUID of item&#8217;s tempalte. </div>
<div><b>    NOTE</b>: this field is supposed to have ShortID value instead of GUID one. This field should not be used in combined queries prior to Sitecore 6.2 releases.</div>
<div>If you decide to add custom fields to your search index and they should have GUID values, you need to store them as ShortID in lower case format. Otherwise search will not be able to find any results. The reason why it happens is because Lucene recognizes GUIDs and applies special parsing for them. It works fine if search query has only one field to look into. If it&#8217;s combined/complex query then it fails to find anything even if it&#8217;s correct.</div>
<div>So, remember if you need to filter search results by template, you will have to customize DatabaseCrawler to add another field (e.g. _shorttemplateid) to store item template id in ShortID format.</div>
<div></div>
<div><b>Sample 1: Find all item references</b></div>
<div></div>
<div>  &#8230;..</div>
<div><span>    QueryBase query = FieldQuery(&#8220;_links&#8221;, ShortID.Encode(item.ID).ToLowerInvariant());</span></div>
<div><span>    SearchHits results = searchContext.Search(query);</span></div>
<div>  &#8230;..</div>
<div></div>
<div><b>Sample 6: Find all items based on specified template</b></div>
<div></div>
<div>
<div>  &#8230;..</div>
<div>    // Prior to Sitecore 6.2 release, you will need to add and use _shorttemplateid field</div>
<div><span>    QueryBase query = FieldQuery(&#8220;_template&#8221;, ShortID.Encode(item.ID).ToLowerInvariant());</span></div>
<div><span>    SearchHits results = searchContext.Search(query);</span></div>
<div>  &#8230;..</div>
<div></div>
<div><b>Sample 7: Find items that are descendants of a specified one</b></div>
<div>
<div>  &#8230;..</div>
<div><span>    QueryBase query = FieldQuery(&#8220;_path&#8221;, ShortID.Encode(item.ID).ToLowerInvariant());</span></div>
<div><span>    SearchHits results = searchContext.Search(query);</span></div>
<div>  &#8230;..</div>
<div></div>
<div><b>Sample 8: Find items of a parent and belong to a specific template</b></div>
<div>
<div>  &#8230;..</div>
<div><span>    CombinedQuery query = new CombinedQuery();</span></div>
<div><span>
<div>    query.Add(new FieldQuery(&#8220;_shorttemplateid&#8221;, ShortID.Encode(templateId).ToLowerInvariant()), QueryOccurance.Must);</div>
<div>    query.Add(new FieldQuery(&#8220;_path&#8221;, ShortID.Encode(parent.ID).ToLowerInvariant())), QueryOccurance.Must);</div>
<p></span></div>
<div>  &#8230;..</div>
<div></div>
<div>That&#8217;s all I wanted to tell about Lucene search index in Sitecore 6. I hope it will help Lucene beginners to better understand the concept and get up to speed with Lucene search index abilities.</div>
<div>Enjoy!</div>
</div>
</div>
</div>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/34912_5251195438749660493-7431877801576788621?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html">http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/&amp;title=Working with Lucene Search Index in Sitecore 6. Part III &#8211; Code examples">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-iii-code-examples/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with Lucene Search Index in Sitecore 6. Part II &#8211; How it works</title>
		<link>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/</link>
		<comments>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/</guid>
		<description><![CDATA[Here is second part of the Lucene search index overview for Sitecore 6. In this part we&#8217;ll take a look at configuration settings and talk about how it works. Sitecore 5 has Lucene engine as well. Let&#8217;s step one Sitecore version back and see how Lucene works there. In web.config file there is a section [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">Here is second part of the Lucene search index overview for Sitecore 6. In this part we&#8217;ll take a look at configuration settings and talk about how it works.
<div></div>
<div>Sitecore 5 has Lucene engine as well. Let&#8217;s step one Sitecore version back and see how Lucene works there.  In web.config file there is a section <span>/sitecore/indexes</span> that contains Lucene index configuration. When index is configured, it should be added to <span>/sitecore/databases/database/indexes</span> section.</div>
<div>
<div>The <i>web</i> database does not have a search index by default. Even if you add it to aforementioned section, it won&#8217;t work. Why? Because index configuration relies on <i>HistoryEngine</i> functionality. By default the <i>web</i> database does not have it. It&#8217;s easy to add it though. Just add the <i>HistoryEngine</i> configuration section to the database.</div>
<div>You can find more configuration details from <a href="http://sdn.sitecore.net/Articles/Administration/Lucene%20Search%20Engine.aspx">this article</a> on <a href="http://sdn.sitecore.net/">SDN</a>. </div>
<div>This index has the same configuration in Sitecore 6. </div>
<div>In addition to it, Sitecore 6 has a new Lucene index functionality. Which is more reliable and has Sitecore level API on top of Lucene one. In some cases you will still have to use Lucene API. For instance to create <i>range</i> queries.</div>
<div>Configuration settings for <i>new</i> search index located under <span>/sitecore/search</span> section. </div>
<div>The <span>analyzer</span> section defines a Lucene analyzer that is used to analyze and index content. </div>
<div>The <span>categories</span> section is used to categories search results. It&#8217;s used for content tree search introduced in Sitecore 6. The search box is located right above the content tree in content editor.</div>
<div>The <span>configuration</span> section has indexes definitions with their configurations. An index definition should be created under <span>/sitecore/search/configuration/indexes</span> node.</div>
<div>First two parameters describe the index name and folder name where it should be stored:</div>
<div>
<div><span></span></div>
<blockquote><div><span><span>&lt;param desc=&#8221;name&#8221;&gt;$(id)&lt;/param&gt;</span></span></div>
<div><span><span>&lt;param desc=&#8221;folder&#8221;&gt;my_index_folderName&lt;/param&gt;</span></span></div>
</blockquote>
<div><span></span></div>
<div>Next setting is the analyzer that should be used for the index:</div>
<div><span><br />
<blockquote><span>&lt;Analyzer ref=&#8221;search/analyzer&#8221; /&gt;</span></p></blockquote>
<p></span></div>
<div>Lucene StandardAnalyzer covers most of the case scenarios. But it&#8217;s possible to use any other analyzer if it&#8217;s needed.</div>
</div>
<div>Following setting defines locations for the index:</div>
<div><span><br />
<blockquote><span>&lt;locations hint=&#8221;list:AddCrawler&#8221;&gt;</span></p></blockquote>
<p></span></div>
<div>It&#8217;s possible to have multiple locations for one index. Moreover it&#8217;s even possible to have content from different databases in the same index. Every child of the <i>locations</i> node has its own configuration for a particular part of the content. A name of <i>location</i> node is not predefined. You&#8217;re welcome to name it the way you want. For example:</div>
<div>
<div><span></span></div>
<blockquote><div><span><span>&lt;locations hint=&#8221;list:AddCrawler&#8221;&gt;  </span></span></div>
<p><span> <span><span><span> &lt;</span></span><span><span>sdn-site</span></span><span><span> type=&#8221;Sitecore.Search.Crawlers.DatabaseCrawler, Sitecore.Kernel&#8221;&gt;</span></span></span></span>
<div><span><span>    &#8230;</span></span></div>
<div><span><span>  </span></span></div>
<p><span>  <span><span><span>&lt;/</span></span><span><span>sdn-site</span></span><span><span>&gt;</span></span></span></span>
<div><span><span>&lt;/locations&gt;</span></span></div>
</blockquote>
<div><span></span></div>
</div>
<div>Every location has a <span>database</span> section. It defines indexing database for the location.</div>
<div>Then <span>root</span> section. The database crawler will index content beneath this path.</div>
<div>Next sibling node is the <span>include</span> section. Here it&#8217;s possible to add templates items of which should be included to the index or excluded from it.</div>
<div>Example:</div>
<div>
<div><span></span></div>
<blockquote><div><span><span>&lt;include hint=&#8221;list:IncludeTemplate&#8221;&gt;  </span></span></div>
<p><span>  &lt;sampleItem&gt;{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}&lt;/sampleItem&gt;</span></p></blockquote>
<blockquote><div><span><span>&lt;/include&gt;</span></span></div>
<div><span><span>&lt;include hint=&#8221;list:ExcludeTemplate&#8221;&gt;  </span></span></div>
<p><span>  &lt;layout&gt;{3A45A723-64EE-4919-9D41-02FD40FD1466}&lt;/layout&gt;</span>
<div><span><span>&lt;/include&gt;</span></span></div>
</blockquote>
<div><span></span></div>
</div>
<div>It does not make sense to use both of these settings for the one location. Use only one of them.</div>
<div>Next location setting is <span>tags</span> section. Here you can tag indexed content and use it during the search procedure.</div>
<div>Last setting is <span>boost</span> section. Here you have an ability to boost indexed content among other content that belongs to other locations.</div>
<div>And last but not the least, this search index uses the same <i>HistoryEngine</i> mechanism as old one. So, don&#8217;t forget to copy configuration section from master database to a database where you want to add search index facilities to.</div>
<div></div>
<div>How it all works?</div>
<div>When an action performed on the item, database crawler updates entries in search index for the item. So that information in index is in sync with the one in database. How does it happen if &#8220;<i>item:saved</i>&#8220;, &#8220;<i>item:deleted</i>&#8220;, &#8220;<i>item:renamed</i>&#8220;, &#8220;<i>item:copied</i>&#8220;, &#8220;<i>item:moved</i>&#8221; do not have event handlers that trigger search index update? Thank to <i>HistoryEngine</i> that was mentioned several times already.</div>
<div>It is <i>HistoryEngine</i> that tracks any changes made to the item and fires appropriate event handler to process it.</div>
<div><i>IndexingManager</i> is responsible for all operations to the search index. It subscribes to <i>AddEntry</i> event of <i>HistoryEngine</i> and as soon as an entry added to the <i>History</i> table, it triggers a job that updates the search index(es).</div>
<div>In web.config file there are a few settings that belong to indexing functionality.</div>
<div>
<ul>
<li><b>Indexing.UpdateInterval</b> &#8211; sets the interval between the IndexingManager checking its queue for pending actions. Default value is 5 minutes.<br />What does it mean? If for whatever reason pending job was not executed, the IndexingManager will re-run it if it finds it in pending state after 5 minutes pass.</li>
<li><b>Indexing.UpdateJobThrottle</b> &#8211; sets the minimum time to wait between individual index update jobs. Default value 1 second.<br />When some operation is performed on the item, you can see this entry in Sitecore log file:<br /><i>INFO  Starting update of index for the database &#8216;<span>databaseName</span>&#8216; (<items_number> pending).<br /><span>This setting sets the interval between jobs like this. So that it does not overwhelm all CPU time if you&#8217;re doing massive change to the items.</span></items_number></i></li>
<li><b>Indexing.ServerSpecificProperties</b> &#8211; Indicates if server specific keys should be used for property values (such as &#8216;last updated&#8217;). It&#8217;s off by default.<br />This setting is designed for content delivery environments in web farms. As <i>web</i> database is shared, there could be a situation when one server has updated its search indexes and changed <i>History</i> table in the database. Other servers won&#8217;t update their indexes because <i>HistoryEngine</i> wouldn&#8217;t indicate there was a change. This setting prevents situations like this.</li>
</ul>
<div>Well&#8230; this is it for now. In next part we will take a look at Sitecore Lucene API and create some search queries with it.</div>
<div>Enjoy!</div>
</div>
</div>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/34912_5251195438749660493-2781154286092118419?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in.html">http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/&amp;title=Working with Lucene Search Index in Sitecore 6. Part II &#8211; How it works">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-ii-how-it-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with Lucene Search Index in Sitecore 6. Part I &#8211; Why/When to use</title>
		<link>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/</link>
		<comments>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/</guid>
		<description><![CDATA[How often did you stress yourself thinking on the question &#8220;What&#8217;s the most efficient way to retrieve Sitecore items?&#8221;? Here are possible ways to do it: Sitecore API Sitecore Query SQL custom stored procedures Lucene index Let&#8217;s take a look at each option briefly. Sitecore API &#8211; the most popular way to get an item. [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">How often did you stress yourself thinking on the question &#8220;What&#8217;s the most efficient way to retrieve Sitecore items?&#8221;?
<div>Here are possible ways to do it:
<div>
<ul>
<li>Sitecore API</li>
<li>Sitecore Query</li>
<li>SQL custom stored procedures</li>
<li>Lucene index</li>
</ul>
<div>Let&#8217;s take a look at each option briefly.</div>
<div><b>Sitecore API</b> &#8211; the most popular way to get an item. All you need is an item ID and simple call of GetItem(<id>) method of database instance will get you the latest item version in current language. If you want an item in specific language, not a problem: GetItem(<id>, <language>). Want specify version, not a problem either: GetItem(<id>, <language>, <version>). There are many ways to get an item through Sitecore API. My point is that it&#8217;s the most easiest way to do it.</version></language></id></language></id></id></div>
<div><b>Sitecore Query</b> &#8211; easy way to get a bunch of items filtered by some criteria. Build a string query, which kinda look like XPath query, and run it on a database instance. Read more about <a href="http://sdn.sitecore.net/Reference/Using%20Sitecore%20Query.aspx">Sitecore Query</a>.</div>
<div><b>SQL custom stored procedures</b> &#8211; we all know how to create a SQL stored procedure. Connections strings already exist in Sitecore solution. All you need is to use some SQL management studio to create a stored procedure for the database. The question is why would you do it if API already exists? It makes sense only if you run complex query with lots of filtering conditions so that SQL will return you only items that you&#8217;re searching for.</div>
<div><b>Lucene index</b> &#8211; why would I use separate data storage/data index to get an item from Sitecore database? It does not make sense. Agree, for an item it does not but for a collection of items it has a perfect sense to do it. Why? Maybe because performance is much better when you are working with big amount of data. Moreover that&#8217;s a search index. Which means that data are perfectly organized to be searched.</div>
<div></div>
<div>Let&#8217;s talk about performance characteristics for each of these options and compare them.</div>
<div><i><span>Sitecore API</span></i> &#8211; uses Sitecore data provider to pull out information from the database. If item that we&#8217;re looking for is cached the call to SQL database is avoided and item gets retrieved from one of Sitecore caches. Using Sitecore caches gives you huge performance benefit. That&#8217;s why we always worried about caches configuration in Sitecore solution. What if you need to get a number of items by some criteria, let&#8217;s say template ID and belonging to some category (from here on I&#8217;m gonna use this condition for all item retrieval options). You run foreach or for or any other logic that goes through the content tree and checks for a TemplateID property and category field of every single item. If item resides in cache, it will be quick enough but still the code will have to request every single item from the content tree.</div>
<div><i><span>Sitecore Query</span></i> &#8211; the picture with Sitecore Query is very similar to Sitecore API but it get&#8217;s more slower when number of items is growing. Kim has a good article that explains <a href="http://sitecorekh.blogspot.com/2007_08_01_archive.html">Sitecore Query performance</a>.</div>
<div>NOTE: I&#8217;m not talking about <i><span>fast</span></i> Sitecore Query introduced in Sitecore 6.</div>
<div><span>SQL stored procedures</span> &#8211; it seems to be a good approach to go with if you&#8217;re searching for items through the content tree. The thing is there will be only one stored procedure that executes query by specified criteria. Also you will have to consider caching option for retrieved items if you have very deep content tree and items of some specific time are not gathered under one branch. My point is that it can cost you more then the benefits that you will get. I would go with this approach only if I cannot do it with Lucene resources.</div>
<div><span>Lucene index</span> &#8211; again it&#8217;s search index. It perfectly fits searching options. When you search for items with specified criteria it neither requests an item instance nor runs query over database tables. It goes through the fields that you have in your index and compares their values to your search conditions. The only thing if search query uses custom fields to filter data by, the fields must be added to your index. Otherwise you will get zero results. It&#8217;s very easy to do though. I will describe it in the next part of the article.</div>
<div></div>
<div>Conclusion: Let&#8217;s answer those questions in the topic of this part.</div>
<div><i><span>Why to use lucene index?</span></i></div>
<div>The approach is one of the most (maybe event the best) efficient ones. Search is quick enough that in most cases you don&#8217;t even need to implement custom caching for the retrieved data.</div>
<div><i><span>When to use lucene index?</span></i></div>
<div>When you need to run search queries with specific criteria on huge number of data.</div>
<div></div>
<div>Don&#8217;t forget the rule &#8211; the more complex search query gets the slower it works <img src='http://squad.jpkeisala.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</div>
<div></div>
<div>In next part we will look into Lucene search index introduced in Sitecore 6. </div>
<div>Information about &#8220;old&#8221; Lucene index (it was introduced in Sitecore 5) you can find <a href="http://sdn.sitecore.net/Articles/Administration/Lucene%20Search%20Engine.aspx">here</a>.</div>
</div>
</div>
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/34912_5251195438749660493-1388752313222715085?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2009/10/working-with-lucene-search-index-part-i.html">http://sitecoregadgets.blogspot.com/2009/10/working-with-lucene-search-index-part-i.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/&amp;title=Working with Lucene Search Index in Sitecore 6. Part I &#8211; Why/When to use">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/working-with-lucene-search-index-in-sitecore-6-part-i-whywhen-to-use/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restrict access to advanced media upload options</title>
		<link>http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/</link>
		<comments>http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/</guid>
		<description><![CDATA[Sometimes you want to give an access to Advanced Media Upload for editors. When you do it, they get access to all the advanced options that you might not want to share with them. This package allows you to configure access to advanced media upload options by tighten security on Sitecore items. After installing the [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">Sometimes you want to give an access to Advanced Media Upload for editors. When you do it, they get access to all the advanced options that you might not want to share with them.
<div>This package allows you to configure access to advanced media upload options by tighten security on Sitecore items.</div>
<div>After installing the package, you can configure advanced options access for presets items at /sitecore/System/Settings/Media/Presets path.</div>
<div></div>
<div><a href="http://1.bp.blogspot.com/_gDIVYhqZmFo/Sl0Jb5G2tII/AAAAAAAAHDA/SvpsQPtewtw/s1600-h/MediaUploadPresets.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 214px;" src="http://1.bp.blogspot.com/_gDIVYhqZmFo/Sl0Jb5G2tII/AAAAAAAAHDA/SvpsQPtewtw/s400/MediaUploadPresets.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5358449506431448194" /></a></div>
<p>Download <a href="http://scusainc.com/SupportResources/ivan/Media/AdvancedMediaUploadPresets/AdvancedMediaUploadPresets-1.0.0.zip">the package</a>.
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/34912_5251195438749660493-2860592728484151655?l=sitecoregadgets.blogspot.com" alt="" /></div>
</div>
<h4>Sitecore Gadgets</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoregadgets.blogspot.com/2009/07/restrict-access-to-advanced-media.html">http://sitecoregadgets.blogspot.com/2009/07/restrict-access-to-advanced-media.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/&amp;title=Restrict access to advanced media upload options">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/restrict-access-to-advanced-media-upload-options/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sitecore Media Library Performance Optimization Checklist</title>
		<link>http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/</link>
		<comments>http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 09:13:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sitecore Blogs]]></category>

		<guid isPermaLink="false">http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/</guid>
		<description><![CDATA[Here is a quick checklist that you can use in order to get more performance out of your Sitecore Media Library’s delivery. 1. Ensure data/item/prefetch caches are of a sufficient size. Check our cache configuration reference The following shared source modules should be useful in this exercise:http://trac.sitecore.net/CachingManagerhttp://trac.sitecore.net/CacheTuner 2. Ensure client caching is properly configured (MediaResponse.XXX [...]]]></description>
			<content:encoded><![CDATA[<div class="wpomatic-post">Here is a quick checklist that you can use in order to get more performance out of your Sitecore Media Library’s delivery.<br />
<a name='more'></a><br />
<a href="http://lh3.ggpht.com/-Y_IP05wJao4/TpyNERqlo4I/AAAAAAAAf14/4V67Umy9zw0/s1600-h/media_library%25255B14%25255D.png"><img alt="media_library" border="0" height="180" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/c0dc9_media_library_thumb%25255B8%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="media_library" width="377" /></a><br />
1. Ensure data/item/prefetch caches are of a sufficient size.</p>
<ul>
<ul>
<li>Check our <a href="http://%20http//sdn.sitecore.net/upload/sitecore6/sc62keywords/cache_configuration_reference_a4.pdf">cache configuration reference</a>  </li>
<li>The following shared source modules should be useful in this exercise:<br /><a href="http://trac.sitecore.net/CachingManager">http://trac.sitecore.net/CachingManager</a><br /><a href="http://trac.sitecore.net/CacheTuner">http://trac.sitecore.net/CacheTuner</a> </li>
</ul>
</ul>
<p>2. Ensure client caching is properly configured (MediaResponse.XXX settings).<br />
3. Media Library structure – make sure the tree is balanced.<br />
4. Change MediaLinkPrefix from ~/media to something else, for example &#8220;-/media&#8221;:</p>
<blockquote><p>
- set the value of the “Media.MediaLinkPrefix” to alternative prefix: </p></blockquote>
<blockquote>
<div>
<div>
<pre><span>&lt;</span><span>setting</span> <span>name</span><span>="Media.MediaLinkPrefix"</span> <span>value</span><span>="-/media"</span> <span>/&gt;</span> </pre>
</div>
</div>
</blockquote>
<blockquote><p>
-add the following line to the customHandlers section: </p>
<pre><span>&lt;</span><span>customHandlers</span><span>&gt;</span>
   <strong><span>&lt;</span><span>handler</span> <span>trigger</span><span>="-/media/"</span> <span>handler</span><span>="sitecore_media.ashx"</span> <span>/&gt;</span></strong>
   <span>&lt;</span><span>handler</span> <span>trigger</span><span>="~/media/"</span> <span>handler</span><span>="sitecore_api.ashx"</span> <span>/&gt;</span>
   …
<span>&lt;/</span><span>customHandlers</span><span>&gt;</span>
</pre>
</blockquote>
<blockquote>
<div>
This really helps for high traffic websites. Apparently tilde in the path forces different way of resolving the system permissions on a resource on Windows Server.</div>
</blockquote>
<div>
5. Consider IIS kernel and/or output caching, but keep in mind <a href="http://sdn.sitecore.net/Products/Sitecore%20V5/Sitecore%20CMS%206/ReleaseNotes/KnownIssues%20Recommended/ASP%20NET%20Output%20Caching.aspx">this consideration</a>.</div>
<p>6. Consider adding other edge caching options in front of the web servers.<br />
7. Leverage CDN like AKAMAI.</p>
<blockquote><p>
Some links and food for thought:</p>
<ul>
<li><a href="http://sdn.sitecore.net/Scrapbook/Changing%20media%20URLs%20in%20Sitecore%206.aspx">http://sdn.sitecore.net/Scrapbook/Changing%20media%20URLs%20in%20Sitecore%206.aspx</a>
</li>
<li><a href="http://www.sitecoredevelopment.com/en/MarkGraber/Using-Akamai-Net-Storage-for-Sitecore-Media-Items.aspx">http://www.sitecoredevelopment.com/en/MarkGraber/Using-Akamai-Net-Storage-for-Sitecore-Media-Items.aspx</a>
</li>
<li><a href="http://sdn.sitecore.net/Forum/ShowPost.aspx?postid=18768">http://sdn.sitecore.net/Forum/ShowPost.aspx?postid=18768</a>
</li>
<li><a href="http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=27646">http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=27646</a>
</li>
<li><a href="http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=15132">http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=15132</a>
</li>
<li><a href="http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=26647">http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?postid=26647</a> </li>
</ul>
</blockquote>
<p>8. Use dedicated “Sitecore media server” (e.g. replace hostname in media links to point to another Sitecore instance; would require some customization).</p>
<blockquote><p>
Some great stuff here:</p></blockquote>
<ul>
<ul>
<li><a href="http://mcore.wordpress.com/2009/11/02/dedicated-image-server-and-sitecore/">http://mcore.wordpress.com/2009/11/02/dedicated-image-server-and-sitecore/</a>
</li>
<li><a href="http://mcore.wordpress.com/2011/01/02/dedicated-image-server-in-sitecore-part-2/">http://mcore.wordpress.com/2011/01/02/dedicated-image-server-in-sitecore-part-2/</a> </li>
</ul>
</ul>
<p>Thanks to the guys from our brilliant customer service for helping me to come up with a more complete list.</p>
<hr />
<div><img width="1" height="1" src="http://squad.jpkeisala.com/wp-content/plugins/wp-o-matic/cache/c0dc9_18939862-4927389348987732232?l=sitecoreblog.alexshyba.com" alt="" /></div>
</div>
<h4>Consulting and Supporting Sitecore Developer Community</h4>
<div class="wpomatic-feedlogo"></div>
<div  class="wpomatic-source">
Source:<br />
<a href="http://sitecoreblog.alexshyba.com/2011/10/sitecore-media-library-performance.html">http://sitecoreblog.alexshyba.com/2011/10/sitecore-media-library-performance.html</a>
</div>
<hr />
<p><small>&copy; admin for <a href="http://squad.jpkeisala.com">Sitecore Fetch Squad</a>, 2011. |
<a href="http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/">Permalink</a> |
<a href="http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/#comments">No comment</a> |
Add to
<a href="http://del.icio.us/post?url=http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/&amp;title=Sitecore Media Library Performance Optimization Checklist">del.icio.us</a>
<br/>
Post tags: <br/>
</small></p>
<p><small>Feed enhanced by <a href='http://planetozh.com/blog/my-projects/wordpress-plugin-better-feed-rss/'>Better Feed</a> from  <a href='http://planetozh.com/blog/'>Ozh</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://squad.jpkeisala.com/2011/10/sitecore-media-library-performance-optimization-checklist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.987 seconds -->

