Scenario : Need to use SharePoint 2010 Out Of Box(OOB) Search.asmx to perform
People Search from SharePoint profile data. Implement filters in search
including phonetic search, refinements and use specific relevance model.
This is supposed to be
relatively straight forward. You can consume the search services from any
SiteCollection URL. For Ex:
https://MyWebApp.com/sites/MySiteCollection/_vti_bin/search.asmx. You can
prefix _vti_bin/search.asmx at any level (webapp/sitecollection/subsite) to
consume the OOB web service. This is same as consuming any other OOB service in
SharePoint.
You would use either
Query or QueryEx methods based on whether you want your output in XML format or
as a DataSet. In my scenario the data is required in an XML format. The Query
method accepts a string input, which is an XML structure for SharePoint Query.
For more details refer to Search Service on MSDN
The Wrong Way, which
works:
<?xml version="1.0"
encoding="utf-8" ?>
<QueryPacket xmlns="urn:Microsoft.Search.Query"
Revision="1000">
<Query domain="QDomain">
<SupportedFormats>
<Format>urn:Microsoft.Search.Response.Document.Document</Format>
</SupportedFormats>
<Context>
<QueryText
language="en-US" type="MSSQLFT">SELECT
AccountName, Title, FirstName,
LastName,JobTitle, PreferredName, Manager, MobilePhone, WorkPhone,
Department,
Function,
Division, OrgDirect, OrgsManaged, Assistant, company, Country, region,
City, State,
locationsitename, WorkEmail, Path, PictureURL, workassignment,
EmployeeType,
Prefix, Pager, fax, PostalAddress1, PostalAddress2, PostalCode
FROM
SCOPE()
WHERE ("DAV:contentclass"
= 'urn:content-class:SPSPeople')
AND CONTAINS ('"John*"')
AND ("Country" = 'USA')
AND ("peoplefinder"
= 'display') ORDER BY "LASTNAME" ASC, "FIRSTNAME"
ASC </QueryText>
</Context>
<Range>
<StartAt>1</StartAt>
<Count>30</Count>
</Range>
</Query>
</QueryPacket>
The above query almost
works at least in the above scenario. We are doing an all fields search for
John and filtering the country by USA and getting the first 30 results of the
result set. We can add more AND conditions in the QueryText if we need more filters.
However the problem
comes when we want to include Phonetic Search Results or would need to apply a
specific relevance model. As per the syntax on MSDN, its a straight forward
like adding <EnablePhonetic>true</EnablePhonetic>
after the Range attribute. However it doesn't work with the above approach. Any
additional attributes like Stemming, Relevance Model will not work with the
above structure.
The Right Way:
Below is the right way
of consuming the Search.asmx for people search results. The difference is you
apply a language attribute to the QueryText and provide the list of each of the
properties you need.
<?xml version="1.0"
encoding="utf-8"?>
<QueryPacket xmlns="urn:Microsoft.Search.Query"
Revision="1000">
<Query domain="QDomain">
<SupportedFormats>
<Format>urn:Microsoft.Search.Response.Document.Document</Format>
</SupportedFormats>
<Context>
<QueryText
language="en-US" type="STRING">
John AND COUNTRY:"USA" AND peoplefinder:"display"
Scope:"People"</QueryText>
</Context>
<Properties>
<Property
name = 'AccountName'/>
<Property
name = 'Title'/>
<Property
name = 'FirstName'/>
<Property
name = 'LastName'/>
<Property
name = 'JobTitle'/>
<Property
name = 'PreferredName'/>
<Property
name = 'Manager'/>
<Property
name = 'MobilePhone'/>
<Property
name = 'WorkPhone'/>
<Property
name = 'Department'/>
<Property
name = 'Function'/>
<Property
name = 'Division'/>
<Property
name = 'OrgDirect'/>
<Property
name = 'OrgsManaged'/>
<Property
name = 'Assistant'/>
<Property
name = 'Company'/>
<Property
name = 'Country'/>
<Property
name = 'Region'/>
<Property
name = 'City'/>
<Property
name = 'State'/>
<Property
name = 'locationsitename'/>
<Property
name = 'WorkEmail'/>
<Property
name = 'Path'/>
<Property
name = 'PictureURL'/>
<Property
name = 'workassignment'/>
<Property
name = 'EmployeeType'/>
<Property
name = 'Prefix'/>
<Property
name = 'Pager'/>
<Property
name = 'fax'/>
<Property
name = 'PostalAddress1'/>
<Property
name = 'PostalAddress2'/>
<Property
name = 'Postalcode'/>
</Properties>
<Range>
<StartAt>1</StartAt>
<Count>30</Count>
</Range>
<EnableStemming>true</EnableStemming>
<TrimDuplicates>true</TrimDuplicates>
<IgnoreAllNoiseQuery>true</IgnoreAllNoiseQuery>
<IncludeRelevanceResults>true</IncludeRelevanceResults>
<IncludeSpecialTermResults>true</IncludeSpecialTermResults>
<IncludeHighConfidenceResults>true</IncludeHighConfidenceResults>
<EnablePhonetic>true</EnablePhonetic>
<RelevanceModel>D9BFB1A1-9036-4627-83B2-BBD9983AC8A1</RelevanceModel>
</Query>
</QueryPacket>
The above XML
Query works perfectly fine for all the filters including the RelevanceModel and
Include/Exclude Phonetic results.
Great article and thanks for sharing, You are blog is more informative.
ReplyDeleteSharePoint Development
It is very good and useful .Learned a lot of new things from your post!Good creation ,thanks for good info .Net Online Training
ReplyDelete