Refreshing #Sitecore Links Database for an Item and Seeing What Links to the Item

I had a client and recently a question came up on Sitecore Slack about the Sitecore link database and how you can find what items link to an item. This is one of those simple solutions that I may refer to in the future and also it may help someone else. In my client’s case they needed to know what media images linked to the item. I will keep this short and sweet. You can see my comments in the code below. Let me know if you have any questions.


Keeping #Sitecore #SOLR Index Names Unique for Multiple Projects

One of the things I recently ran into was what should you do if you have multiple projects with the same SOLR index name. SOLR does not allow you to have the same name for an index. For instance you can’t have more than one sitecore_master_index. You will be warned and unable to if you try and create one with the same name. Also if you rebuild the indexes it will overwrite the index data for the other site you were working on. So I went on Sitecore Slack looking for help. Where Sitecorey gave me a great idea. Basically you would prefix the configuration entry core with the name of the site in each index file. See below for an example.

Your index name should reflect that name as well in the SOLR index directory.

Now this did solve the issue of having multiple indexes, but a few people on the team wanted to take it a step further. They wanted to see indexes prefixed with site name from the control panel index rebuild. So I created a config transform this time for it. Keep in mind this is always a smart idea to keep the original files safe. Basically I just replaced the id value.

From my understanding the SIM installer can also help with the prefixing of index names. I haven’t used it for that yet as my site was already installed, but in the future that is something I will consider. Let me know if you have any questions.

Making the #Sitecore Switch from #Lucene to #SOLR with Custom Indexes

Recently I did my first conversion from Lucene to SOLR. With Lucene being phased out in Sitecore 9 this will probably be more common. You can find a lot of different installation guides in installing SOLR, but there are a few things that tripped me up that I want to prevent others from having to deal with.

Avoid Pitfalls

  • Make sure every Lucene config is disabled. Even the ones in the sub folders.
  • Make sure all the SOLR configs are enabled even the ones in the sub folders.
  • Make sure you don’t have any Cores with the same name inside the core.properties file. I had Sitecore_Master_Index in more than one file and all my Cores would disappear every time I restarted until I corrected the name.

Custom Indexes Differences

Some of this is obvious as you can replace Lucene with Solr, but some were not so obvious to me and I had to do some research and ask for help. I highlighted the less obvious ones.

From this:

<index
id=acme_widgetgroups_index” type=Sitecore.ContentSearch.LuceneProvider.LuceneIndex, Sitecore.ContentSearch.LuceneProvider>

To this:

<index
id=acme_widgetgroups_index” type=Sitecore.ContentSearch.SolrProvider.SolrSearchIndex, Sitecore.ContentSearch.SolrProvider>

From this:

<configuration
ref=contentSearch/indexConfigurations/defaultLuceneIndexConfiguration>

To this:

<configuration
ref=contentSearch/indexConfigurations/defaultSolrIndexConfiguration>

From this:

<fieldMap
type=Sitecore.ContentSearch.FieldMap, Sitecore.ContentSearch>

To this:

<fieldMap
ref=contentSearch/indexConfigurations/defaultSolrIndexConfiguration/fieldMap>

From this:

<field fieldName=widgetfilters” storageType=YES” indexType=TOKENIZED” vectorType=NO” boost=1f” type=System.String” settingType=Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider />

To this:

<field fieldName=widgetfilters” returnType=string />

From this:

<documentOptions
type=Sitecore.ContentSearch.LuceneProvider.LuceneDocumentBuilderOptions, Sitecore.ContentSearch.LuceneProvider>

To this:

<documentOptions
type=Sitecore.ContentSearch.SolrProvider.SolrDocumentBuilderOptions, Sitecore.ContentSearch.SolrProvider>

I hope this helps you as you do your conversion. If you have any questions, feel free to ask.

Serializing a #Sitecore Computed Index Field (When You Need to Pass an Immense Amount of Data)

Recently I worked on a Data Exchange Framework process that involved extracting several records. Each record would eventually be inserted into an external table as they were basically rows. The DEF process was slow creating the records so I created a computed index field to handle creating the records and the DEF process would just need to read and insert the records accordingly. Problem was most computed index fields usually return a small value. In this case it could be several rows of data. The solution was simple though. Serialize a list of objects then deserialize it and let the DEF processor take it from there.

In my example the computed index field is created using an Image field class which contains a list of ImageInfo objects. You can fill in and create the index however you want. See below.

public class
 Image
 {
  [IndexField("imageinformation")]
  publicList<ImageInfo> ImageInformation { get; set; }
  [IndexField("images")]
  public string Imagelist { get; set; }
  [IndexField("_templatename")]
   public string TemplateName { get; set; }
 }

public class ImageInfo
 {
  public string EntityId { get; set; }
  public string caption1 { get; set; }
  public string caption2 { get; set; }
  public string freeformcaptions { get; set; }
  public string url { get; set; }
  }

As stated above, Image contains a list of ImageInfo objects. I used Newtonsoft to Serialize it.

return JsonConvert.SerializeObject(image.ImageInformation); 

This is an example of what the serialized data looks like:

“[{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Streetscape3.ashx\”},{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Streetscape.ashx\”},{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Streetscape1.ashx\”},{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Exterior.ashx\”},{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Streetscape3.ashx\”},{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Streetscape4.ashx\”},{\”EntityId\”:\”4aa575d5-af18-466f-8e56-a06494ca6d16\”,\”caption1\”:\”NoCaption\”,\”caption2\”:null,\”freeformcaptions\”:null,\”url\”:\”https://acme.com/-/media/Images/Acme/Products/location/area51/subspecies/images/Streetscape5.ashx\”}]”

This is the computed index in the index configuration.

<fields hint="raw:AddComputedIndexField">
<!-- Custom Computed Fields -->
<!-- Default SC Fields -->
<field fieldName="images">Acme.Feature.Website.ComputedFields.CustomReporting.ImagesComputedField, Acme.Your.Website</field>
 </fields> 

In the process method of the DEF you can then deserialize the field and do your processing.

var imageinfo = JsonConvert.DeserializeObject<List<ImagesComputedField.ImageInfo>>(image.Imagelist);
foreach (var imagedet in imageinfo)
{
 UpdateDataTable(new Guid(imagedet.EntityId), imagedet.caption1, 
 imagedet.caption2,imagedet.freeformcaptions, imagedet.url); 
}

So that is it. Not too bad and will solve a lot of issues where you need to move a lot of data. The DEF process went from 15 plus minutes to less than a minute once this index was created.