Wednesday, June 13, 2012

SharePoint Search Results shows first line instead of Title field of Document


Office documents stored in SharePoint 2010 which have their title field populated show an incorrect title in the default search results. The screen shot below shows the search results for the following document:
Filename: Test document 1.docx 

The title that is displayed as the link to the document at the top of the individual search result is the first line of text from the document, not the title (metadata) field. If title field for the document is not set, the filename is displayed as the link to the document at the top of the individual search result, not the first line of text from the document.
As per Microsoft it is normal behavior as it tries to give you more relevant result to your search.
To correct this behavior:
  • Edit the ‘EnableOptimisticTitleOverride’ key and modify its value to 0:
  • Open registry editor
  • Navigate to HKLM\SOFTWARE\Microsoft\Office Server\14.0\Search\Global\Gathering Manager
  • Restart the SharePoint Server Search 14 service at admin command prompt.
    1. net stop osearch14
    2. net start osearch14
  • Repeat the above steps for all SharePoint servers in the farm.
  • Perform a full crawl on the SharePoint content source(s)
Once the full crawl has completed, performing the search again gives the title field as the search result title for a document which has the title field populated
The following can be copied into a .reg file to automate setting the key, or the key could be set using PowerShell:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Global\Gathering Manager]
"EnableOptimisticTitleOverride"=dword:00000000

Please leave your comments/feedback.

SharePoint SPWeb Property ParserEnabled

ParserEnabled :- property controls demotion and promotion.
Promotion :- The process of extracting values from properties of a document and writing those values to corresponding columns on the sharepoint list or document library where the document is stored.

Demotion :- The same process in reverse.Read sharepoint list or library columns values and written to document properties.

When ParserEnabled property false there will not be any property demotion and promotion, which means metadata and document file properties will not be in sync.

PowerShell way of Disabling and enabling this property:
Disable ParserEnabled property:
    [system.reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint")
    $site = new-object Microsoft.SharePoint.SPSite("http://mossweb/sites/test")
    $site.RootWeb.ParserEnabled = $false
    $site.RootWeb.Update()

Enable ParserEnabled property or document property promotion:
    $site.RootWeb.ParserEnabled = $true
    $site.RootWeb.Update()

Note:
Disabling ParserEnabled affect:

  1. We can't search in document library using Office document properties.
  2. When you upload image file. Thumbnail will not be generated.
  3. When you save a list template, You will not see it in list template gallery.
If you need to disable this property you need to take care of its effect. Disable it only in special sites. if you want it when you upload document using code disable it temporary using code like below:

using (var site = new SPSite("http://sharepoint-portal"))
{
    using (var web = site.OpenWeb())
    {
       SPFile file = web.GetFolder("Documents").Files["mydoc.docx"]; 
       using (var fs = new FileInfo(@"C:\Documents\mydoc.docx").OpenRead())
 
       {
        documentBytes = ..... // get the documents bytes
       }
       web.ParserEnabled = false;
       web.Update();
       file.SaveBinary(documentBytes);
       web.ParserEnabled = true;  
       web.Update();
    }
}
 
Use the ‘Comments’ form to share your thoughts.

Tuesday, May 29, 2012

Designing large lists and maximizing list performance (SharePoint Server 2010)

This is MSDN article, which is very useful for all the developers who are dealing with the large CMS.

This article provides information about the performance of large document libraries and large lists. The recommendations in this article are the result of a series of performance tests that were conducted with Microsoft SharePoint Server 2010. The focus of this article is on the performance characteristics of large lists and on how different configurations affect the performance of large lists and of the farm. SharePoint Server 2010 has several new improvements that make it easier to create and use large lists. However, creating and implementing large lists still requires careful planning. You must consider many factors, such as information architecture, performance, disaster recovery, and governance. This article covers information architecture and features that are used to implement large lists, and it covers the effect that specific configurations have on performance.

further details at MSDN.

Values chosen in the Document’s Information Panel (DIP) not being saved in the SharePoint library for Managed Metadata columns

We set up a document library with a content type. We got 14 custom columns (6 managed metadata, 2 Person or Group, 5 Text & 1 Date types).  Property promotion/demotion is enabled (SPWeb.ParserEnabled -> true)

When users save a new document into the library they are prompted (DIP) to choose values for these columns.

We are seeing problems related to values chosen in the document’s information panel (DIP) not being saved in the SharePoint library after the document is saved.
The values seem to be saved with the document, when I reopen it from library the values again show in the DIP. So it seems like there is a problem with SharePoint actually reading the document metadata from the Office file even though the metadata is stored in the file.

A related problem arises when I upload a document, set metadata values through the document property form in SharePoint (not in the DIP), then edit the document in Office where I change the metadata values in the DIP, and then resave document back into the SharePoint library. Then the library displays the original metadata values even though they are changed in the Office file itself.

Workaround,
Still following up with MS for the resolution and cause behind broken sync functionality, but workaround to this problem is Add new Managed Metadata Column to the same document library. Test functionality or problem of saving managed metadata. ( it stated working for us). Now delete newly added Managed Metadata column.

Please leave your comments.

Wednesday, May 23, 2012

Jquery and Javascript date calculation /Weekdays calculation.

Jquery and Javascript date calculation /Weekdays calculation.
Open sharepoint page in edit mode.
Add content editor webpart to page at the end.
Add below script to content editor webpart.

// JScript source code
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js">script>
<script src='/_layouts/SP.js' type='text/javascript'>script>
<script type=""text/javascript"">
    var myItems;
    var countHolidays = 0;
 
    $("input[name='CONTROL_NAME$DateTimeField$DateTimeFieldDate']").focusout(function () {
 
        var dtfrom = $("input[name='CONTROL_NAME$DateTimeField$DateTimeFieldDate']").val();
 
        var dtto = $("input[name='CONTROL_NAME$DateTimeField$DateTimeFieldDate']").val();
 
        if (dtfrom.length > 0 && dtto.length > 0) {
            var DaysDiff;
            var bussDays = calcBusinessDays(new Date(dtfrom), new Date(dtto));
            GetHolidays(dtfrom, dtto);
 
            DaysDiff = bussDays - countHolidays;
 
            $("#ctlCONTROL_ID_TextField").val(DaysDiff);
        }
 
    });
 
    function calcBusinessDays(dDate1, dDate2) { // input given as Date objects
        var iWeeks, iDateDiff, iAdjust = 0;
        if (dDate2 < dDate1) return -1; // error code if dates transposed
        var iWeekday1 = dDate1.getDay(); // day of week
        var iWeekday2 = dDate2.getDay();
        iWeekday1 = (iWeekday1 == 0) ? 7 : iWeekday1; // change Sunday from 0 to 7
        iWeekday2 = (iWeekday2 == 0) ? 7 : iWeekday2;
        if ((iWeekday1 > 5) && (iWeekday2 > 5)) iAdjust = 1; // adjustment if both days on weekend
        iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays
        iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2;
 
        iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime()) / 604800000);
 
        if (iWeekday1 <= iWeekday2) {
            iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1);
        } else {
            iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2);
        }
 
        iDateDiff -= iAdjust; // take into account both days on weekend
 
        return (iDateDiff + 1); // add 1 because dates are inclusive
    }
 
 
    // this function will find date difference in days.
    function daydiff(first, second) {
        var start = new Date(first);
        var end = new Date(second);
        var diff = new Date(end - start);
        return (diff) / (1000 * 60 * 60 * 24)
    }
 
 
    function GetHolidays(fromdate, todate) {
        var myQueryString = '' + todate + '' + fromdate + '';
 
        var myContext = new SP.ClientContext.get_current();
        var myWeb = myContext.get_web();
        var myList = myWeb.get_lists().getByTitle('Holidays');
        var myQuery = new SP.CamlQuery();
        myQuery.set_viewXml(myQueryString);
        myItems = myList.getItems(myQuery);
        myContext.load(myItems, 'Include(ID, Title, Date, Year)');
        myContext.executeQueryAsync(Function.createDelegate(
                                this, GetHolidaysSuccess),
                     Function.createDelegate(
                                this, GetHolidaysFail));
    }
 
    function GetHolidaysFail(sender, args) {
        //alert('GetEmployeesByAge() failed:' + args.get_message());
        //return false;
    }
 
    function GetHolidaysSuccess(sender, args) {
        var HolidaysCount = myItems.get_count();
 
        var currYear = (new Date).getFullYear();
 
        var holidaysEnumerator = myItems.getEnumerator();
        var holidaysDetails = '';
 
 
 
        // Loop through all items
        while (holidaysEnumerator.moveNext()) {
            // Get current item
            var currentHoliday = holidaysEnumerator.get_current();
            if (currentHoliday.get_item("Year") == currYear) {
                countHolidays = countHolidays + 1;
            }
        }
    }
script>