Обновлять свойство только тогда, когда новое значение отличается от текущего значения - PullRequest
1 голос
/ 14 октября 2011

У меня есть ситуация, когда я обновляю большой объем контента в CMS (Sitecore) в одночасье, когда мне приходится перебирать очень большой объем данных, но нужно применить только несколько обновлений (Приблизительно 320 000 потенциальных полейи в предположении, может быть, 3000, где значения действительно меняются).Я хочу упростить это так, чтобы обновления производились только тогда, когда новое значение отличается от текущего значения.Таким образом, я надеюсь минимизировать объем повторной индексации, которая происходит после выполнения обновлений, а также минимизировать объем контента, который впоследствии публикуется.

Это пример того, что я делаю сейчас

langItem.Fields["Type"].Value = updateNode.SelectSingleNode("./Type").InnerText;

И это то, на что я обращаюсь, чтобы изменить его на

if (langItem.Fields["Type"].Value != updateNode.SelectSingleNode("./Type").InnerText)
    langItem.Fields["Type"].Value = updateNode.SelectSingleNode("./Type").InnerText;

Я чувствую, что должен быть какой-то оператор, который позаботится об этом дляя. Я не думаю, что есть, но если есть, пожалуйста, дайте мне знать, что это такое.Существует много запросов XPath (все мои данные в формате XML), и я чувствую, что повторять их бесполезно, но создание переменных для всех из них также кажется плохой формой.Также есть примеры, когда правая часть включает вызов метода.Я думаю, что в таких ситуациях создание переменной для результата имеет смысл.

Какие еще есть варианты для оптимизации этого?

Ответы [ 2 ]

0 голосов
/ 14 октября 2011

Единственное, о чем я могу думать, это, возможно, использовать синтаксис запроса Sitecore, чтобы попытаться выбрать элементы с различиями.

Например (при условии, что updateNode имеет некоторое свойство ID, которое совпадает с элементом lang)

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();
}

По сути, вы получите удар только по предмету с другим значением.Я не уверен, как именно выстроены ваши данные, так что, возможно, вы можете каким-то образом настроить запрос, но это может немного ускорить процесс (не нужно заполнять данные Item, если естьбез удара)

0 голосов
/ 14 октября 2011

Как насчет простого метода, например

protected void UpdateIfChanged(Field field, string value)
{
    if (field.Value != value)
    {
        field.Value = value;
    }
}

UpdateIfChanged(langItem.Fields["Type"], updateNode.SelectSingleNode("./Type").InnerText);

(код выше не проверен)

Вы также можете добавить его как метод расширения в класс Field, если хотите.

Не уверен, насколько это реально экономит вашу производительность.Действительно, вам нужно избегать сохранения элемента, если поля не были изменены, верно?Это может быть достигнуто путем возврата bool из метода, и если какие-либо поля возвращают true, вы знаете, чтобы сохранить элемент.

...