Update a property only when the new value is different from the current value
I have a situation where I am updating a large amount of co开发者_Go百科ntent in a CMS (Sitecore) overnight in which I have to iterate through a very large amount of data but with only a few updates to be applied (Approximately 320,000 potential fields, and at a guess maybe 3000 where the values actually change). I want to streamline this so that updates are only made when the new value is different to the current value. In this way I hope to minimise the amount of re-indexing that occurs after the updates are made, and also minimise the amount of content that subsequently gets published.
This is an example of what I'm doing now
langItem.Fields["Type"].Value = updateNode.SelectSingleNode("./Type").InnerText;
And this is what I'm looking at changing it to
if (langItem.Fields["Type"].Value != updateNode.SelectSingleNode("./Type").InnerText)
langItem.Fields["Type"].Value = updateNode.SelectSingleNode("./Type").InnerText;
I feel like there should be some kind of operator that would take care of this for me. I don't think there is but if there is please let me know what it is. There are a lot of XPath queries (all my data is in XML) and I feel like repeating them is wasteful, but creating variables for all of them also seems like bad form. Also, there are examples where the right-hand side involves a method call. I think in those situations creating a variable for the result makes sense.
What are some other options for optimising this?
What about just a simple method, e.g.
protected void UpdateIfChanged(Field field, string value)
{
if (field.Value != value)
{
field.Value = value;
}
}
UpdateIfChanged(langItem.Fields["Type"], updateNode.SelectSingleNode("./Type").InnerText);
(above code untested)
You could add this as an extension method to the Field class as well if you prefer.
Not sure how much this actually saves you performance-wise, however. Really you need to avoid saving the item if no fields have changed, right? Could accomplish that by returning a bool from the method, and if any fields return true, you know to save the item.
The only thing I can think of is perhaps using the Sitecore query syntax to try to select the items with differences.
For example (assuming updateNode has some ID property that is the same as the lang item)
var id = updateNode.SelectSingleNode("./Id").InnerText;
var val = updateNode.SelectSingleNode("./Type").InnerText;
var query = rootPathOfItems + "//*[@@id='{" + id + "} and @Type!='" + val + "']";
var item = Sitecore.Context.Database.SelectSingleItem(query);
if (item != null) {
item.Editing.BeginEdit();
item.Fields["Type"].Value = val;
item.Editing.EndEdit();
}
Essentially you will only get a hit on an item that has a different value. I'm not sure exactly how your data is laid out, so maybe you can tweak the query in some fashion, but this might possibly speed things up a bit (doesn't need to fill out an Item
with data if there is no hit)
精彩评论