Friday, April 23, 2010

Batch Process- MetaData update

Hi All,
My friend came up with a requirement to autoupdate metadata fields in a document library when proceeding with a bulk upload activity.

  • Update multiple metadata fields.
  • Fast process (If we use sharepoint DOM it wont be very fast- takes 2-3 minutes and increases as the no of items increase).
  • No new versions should be created on updation 
So i tried with  using Batchprocess which i feel is the fastest of all other methods.  
In the example here im updating two fields Details, and Approved which i am updating using batch process,
The field Approved is a Yes/No field with default value of 'No'.
So i m updating the Details field with 'Update description and time' and the Approved field to 'Yes'.

Note : I'm retreiving and updating the - Created, Created By, Modified, Modifed By - as i couldnt find a way to retain the version as we do in object model coding using SystemUpdate() instead of Update().
Code :-

 StringBuilder batchprocessbuilder = new StringBuilder(); 
string batchFormat = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + try{
"<ows:Batch OnError=\"Return\">{0}</ows:Batch>";

string methodFormat = "<Method ID=\"{0}\">" +
"<SetList>{1}</SetList>" +
"<SetVar Name=\"Cmd\">Save</SetVar>" +
"<SetVar Name=\"ID\">{2}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Approved\">{3}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Details\">{4}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Created\">{5}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Created_x0020_By\">{6}</SetVar>"
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Modified\">{7}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Modified_x0020_By\">{8}</SetVar>" +"</Method>";

string querystring = "<Where><And><Eq><FieldRef Name='Approved' />"+
"<Value Type='Boolean'>No</Value></Eq><Eq><FieldRef Name='Created' />" +
"<Value Type='DateTime'>{0}</Value></Eq></And></Where>";

 using (SPWeb currentweb = SPContext.Current.Web){

 SPList currentlist = currentweb.Lists["DocLib"];

 //just to make sure no versioning is happening. currentlist.EnableVersioning = false;
string listID = currentlist.ID.ToString();
SPQuery query = new SPQuery();
string datetoday = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now);
query.Query = string.Format(querystring, datetoday);
query.ViewAttributes = "Scope= 'Recursive'";
SPListItemCollection listcollectn = currentlist.GetItems(query);
//fileds updating........

int boolApproved = 1;
string strDetails = "UpdateMetaData" +Convert.ToString(DateTime.Now);

SPListItem item = null;
//Use only for loop, foreach will hang a lot....
for(int i=0; i<listcollectn.Count; i++){
int itemID = listcollectn[i].ID;
item = listcollectn.GetItemById(itemID);
DateTime itemdate = Convert.ToDateTime(item["Created"].ToString());
string date = SPUtility.CreateISO8601DateTimeFromSystemDateTime(itemdate);
batchprocessbuilder.AppendFormat(methodFormat, itemID, listID, itemID, boolApproved, strDetails, date, item["Author"], date, item["Author"]);}
string batch = string.Empty;
batch = string.Format(batchFormat, batchprocessbuilder.ToString());
string batchresults = currentweb.ProcessBatchData(batch);
currentlist.EnableVersioning = true;
}}catch (Exception ex){}

Method : 2 : Using Webservice and Jquery

<soapenv:Envelope xmlns:soapenv=""

<soapenv:Header />
<Batch OnError='Continue' ListVersion='1'>
<Method ID='2' Cmd='Update'>
<Field Name='ID'>4</Field>
<Field Name='Title'>Last_Name</Field>
<Field Name='FirstName'>First_Name</Field>

We can use :
Create: <Method ID='1' Cmd='New'>
Update: <Method ID='2' Cmd='Update'>
Delete: <Method ID='3' Cmd='Delete'>