Sitecore Powershell Extention : How Find-Item solved the performance issue

In my last blog post I mentioned that after loading the images in Sitecore with the help of Sitecore Powershell Extension (SPE), I needed to associate the products to the images. I didn’t show that code because it’s a specific requirement. At that time, I thought number of products is close to number of images, that is, 10000. When we started loading actual data from the eCommerce system, client started complaining about the performance of my Powershell Script. I realized actual number of products is way more than 10K, close to 70K.

Following is the portion of the code

		#Associate Product to Image.
		$ImageName=$Image.TrimEnd(".$FileExtension")
		$products=Get-Item master: -Query "/sitecore/content/Product Repository/Products//*[@@templatename='Custom Insite Product' and @Image Name='$ImageName']"
		if($products)
		{
			foreach($product in $products)
			{
				$product.Image=Get-Item $MediaImagePath.TrimEnd(".$FileExtension")
				$productName=$product.DisplayName
				Write-Host "Assigned image $ImageName to '$productName' ..."
			}
		}
		else
		{
			Write-Host "No product found for this image $Image ..."
		}

After some debugging, I found that the highlighted code is taking most of the time. That code is getting all the products that are supposed to use the image the script just loaded. Is it a SPE thing or Sitecore query problem? To find that, I took the query and ran it in XPath builder. Result shown below.

Sitecore Query Result

The query was taking 104 seconds. That’s for one image. For 10K images this script will never finish.

To improve the performance, I started looking at SPE commands to see if I can query the products from the search index, because, the products are already indexed by another process. I found Find-Item and replace the code with the following code.

		#Associate Product to Image.
		$ImageName=$Image.TrimEnd(".$FileExtension")
		$products=Find-Item -Index commerce_products_master_index -Criteria @{Filter = "Equals"; Field = "_templatename"; Value = "Custom Insite Product"}, @{Filter = "Equals"; Field = "Image Name"; Value = "$ImageName"} | Select-Object -Property Path | Get-Item

		if($products)
		{
			foreach($product in $products)
			{
				$product.Image=Get-Item $MediaImagePath.TrimEnd(".$FileExtension")
				$productName=$product.DisplayName
				Write-Host "Assigned image $ImageName to '$productName' ..."
			}
		}
		else
		{
			Write-Host "No product found for this image $Image ..."
		}

The result was amazing. Now the query returns products immediately. For 10K images and 70K products, it’s taking little more than half an hour. That’s acceptable performance for this kind of batch process.

 

Advertisements

About Himadri Chakrabarti

I am a software developer architect and a Sitecore MVP. My professional interest is everything and anything related to Software Architecture, .NET, Sitecore, Node.js, NoSQL etc. Outside of my profession, I am a hobbyist photographer. Link to my photography site http://himadriphotography.com/
This entry was posted in Powershell and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s