in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

December 2011 - Posts

  • How to: Use Refiners with the Search Web Service (FAST Search for SharePoint)

    Yesterday, I talked about how we can use FQL with the Search Web Service.  As promised, I am continuing the series about the search web service to talk about how we can take advantage of refiners.  As you may know, FAST Search for SharePoint gives you exact counts in refinement so why not take advantage of them in your custom search application.  We’ll take a look at how to specify which refiners are returned with your search results.  After that we’ll take a look at how to use those refiners in a query.

    Returning refiners with your results is also quite easy.  All we have to do is add a few elements to the input XML document of the Query or QueryEx method.  Before you add these elements though, you need to know what you want to refine on.  You can refine on any managed property configured to allow refinement (or deep refinement) on the FAST Search Administration page.  We’ll work with some out of the box properties.  You can look up the names for these by examining the Refinement Panel.  In this post, I talk about the Refinement Panel in SharePoint search but in FAST, the Refinement Panel has a different XML file (and managed property names).  Take a look at the XML below and take note of the MappedProperty attribute.  These are out-of-the-box managed properties that we can use including format (file extension), author, sitename, and write (modified date).

    <?xml version="1.0" encoding="utf-8"?>

    <FilterCategories>

      <Category    Title="Result Type"    Description="The file extension of the item"    Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"    MetadataThreshold="1"    NumberOfFiltersToDisplay="4"    MaxNumberOfFilters="20"    ShowMoreLink="True"    MappedProperty="format"    MoreLinkText="show more"    LessLinkText="show fewer"    ShowCounts="Count" />

      <Category    Title="Site"    Description="Which site this document is from"    Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"    MetadataThreshold="1"    NumberOfFiltersToDisplay="4"    MaxNumberOfFilters="20"    ShowMoreLink="True"    MappedProperty="sitename"    MoreLinkText="show more"    LessLinkText="show fewer"    ShowCounts="Count" />

      <Category    Title="Author"    Description="Use this filter to restrict results authored by a specific author"    Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"    MetadataThreshold="1"    NumberOfFiltersToDisplay="4"    MaxNumberOfFilters="20"    ShowMoreLink="True"    MappedProperty="author"    MoreLinkText="show more"    LessLinkText="show fewer"    ShowCounts="Count" />

      <Category    Title="Modified Date"    Description="When the item was last updated"    Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"    MetadataThreshold="1"    NumberOfFiltersToDisplay="6"    SortBy="Custom"    ShowMoreLink="False"    MappedProperty="write"    ShowCounts="Count" >

        <CustomFilters MappingType="RangeMapping" DataType="Date" ValueReference="Relative" ShowAllInMore="False">

          <CustomFilter CustomValue="Past 24 Hours">

            <OriginalValue>-1..</OriginalValue>

          </CustomFilter>

          <CustomFilter CustomValue="Past Week">

            <OriginalValue>-7..</OriginalValue>

          </CustomFilter>

          <CustomFilter CustomValue="Past Month">

            <OriginalValue>-30..</OriginalValue>

          </CustomFilter>

          <CustomFilter CustomValue="Past Six Months">

            <OriginalValue>-183..</OriginalValue>

          </CustomFilter>

          <CustomFilter CustomValue="Past Year">

            <OriginalValue>-365..</OriginalValue>

          </CustomFilter>

          <CustomFilter CustomValue="Earlier">

            <OriginalValue>..-365</OriginalValue>

          </CustomFilter>

        </CustomFilters>

      </Category>

      <Category    Title="Company"    Description="Use this filter to restrict results by company"    Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"    MetadataThreshold="1"    NumberOfFiltersToDisplay="4"    MaxNumberOfFilters="20"    ShowMoreLink="True"    MappedProperty="companies"    MoreLinkText="show more"    LessLinkText="show fewer"    ShowCounts="Count" />

      <Category    Title="Managed Metadata Columns"    Description="Managed metadata of the documents"    Type="Microsoft.Office.Server.Search.WebControls.TaxonomyFilterGenerator"    MetadataThreshold="3"    NumberOfFiltersToDisplay="3"    MaxNumberOfFilters="20"    ShowMoreLink="True"    MappedProperty="owsmetadatafacetinfo"    MoreLinkText="show more"    LessLinkText="show fewer" />

      <Category    Title="Tags"    Description="All managed metadata of the documents and social tags"    Type="Microsoft.Office.Server.Search.WebControls.TaxonomyFilterGenerator"    MetadataThreshold="3"    NumberOfFiltersToDisplay="3"    MaxNumberOfFilters="20"    ShowMoreLink="True"    MappedProperty="owsmetadatafacetinfo"    MoreLinkText="show more"    LessLinkText="show fewer"    ShowCounts="Count" />

    </FilterCategories>

    We’ll take a look at format and author first.  The managed property for managed metadata fields, owsmetadatafacetinfo, requires a bit more explaining.  To add Refinement to your search results, you just need to add the IncludeRefinementResults element somewhere inside your Query element.  You then specify the name of the managed properties that you want in individual Refiner elements.  Here is what the raw XML looks like.

    <IncludeRefinementResults>

      <Refiners>

        <Refiner>author</Refiner>

        <Refiner>write</Refiner>

        <Refiner>sitename</Refiner>

        <Refiner>format</Refiner>

        <Refiner>owsmetadatafacetinfo</Refiner>

      </Refiners>

    </IncludeRefinementResults>

    To use it in the code, I am using a StringBuilder like before.  Here is what the whole string looks like.

    queryXml.Append("<QueryPacket xmlns=\"urn:Microsoft.Search.Query\" Revision=\"1000\">");

    queryXml.Append("<Query domain=\"QDomain\">");

    queryXml.Append("<SupportedFormats>");

    queryXml.Append("<Format>");

    queryXml.Append("urn:Microsoft.Search.Response.Document.Document");

    queryXml.Append("</Format>");

    queryXml.Append("</SupportedFormats>");

    queryXml.Append("<Range>");

    queryXml.Append("<Count>50</Count>");

    queryXml.Append("</Range>");

    queryXml.Append("<Context>");

    queryXml.Append("<QueryText language=\"en-US\" type=\"FQL\">");

    queryXml.Append(searchQuery);

    queryXml.Append("</QueryText>");

    queryXml.Append("</Context>");

    queryXml.Append("<IncludeRefinementResults>");

    queryXml.Append("<Refiners>");

    queryXml.Append("<Refiner>author</Refiner>");

    queryXml.Append("<Refiner>write</Refiner>");

    queryXml.Append("<Refiner>sitename</Refiner>");

    queryXml.Append("<Refiner>format</Refiner>");

    queryXml.Append("<Refiner>owsmetadatafacetinfo</Refiner>");

    queryXml.Append("</Refiners>");

    queryXml.Append("</IncludeRefinementResults>");

    queryXml.Append("</Query>");

    queryXml.Append("</QueryPacket>");

    I added several refiners in my case which we will talk about.  The rest of the code to execute the query is exactly the same from yesterday’s post.  Let’s look at a snippet of the results.  For each refiner returns you will get a RefinementResults element returned along with your regular RelevantResults elements that you may be accustomed to by now.  Note, that the RefinementResults elements are not grouped in any sort of parent element like the RelevantResults are. Here is a snippet.

    <RefinementResults diffgr:id="RefinementResults19" msdata:rowOrder="18">

      <RefinerName>format</RefinerName>

      <RefinementName>Microsoft Word</RefinementName>

      <RefinementValue>^"Microsoft Word"$</RefinementValue>

      <RefinementToken>AQ5NaWNyb3NvZnQgV29yZAZmb3JtYXQBAl4iAiIk</RefinementToken>

      <RefinementCount>28</RefinementCount>

    </RefinementResults>

    <RefinementResults diffgr:id="RefinementResults20" msdata:rowOrder="19">

      <RefinerName>format</RefinerName>

      <RefinementName>Web Page</RefinementName>

      <RefinementValue>^"Web Page"$</RefinementValue>

      <RefinementToken>AQhXZWIgUGFnZQZmb3JtYXQBAl4iAiIk</RefinementToken>

      <RefinementCount>27</RefinementCount>

    </RefinementResults> 

    If you were to write custom code to display these, I recommend using LINQ to XML and grouping elements that have matching RefinerName values.  In the case above, format is allowing us to refine by file extension.  The RefinementName element contains (usually) a human-readable value to display for the refiner.  The exact count of results can be found in RefinementCount.  Lastly, I will point out the RefinentToken.  This allows us to issue a subsequent query using that refiner.  We’ll talk about that shortly after I cover some more details on the results.

    When refining by date managed properties (such as write), things get a little more complicated.  Take a look at the refinement results, it gave me.

    <RefinementResults diffgr:id="RefinementResults16" msdata:rowOrder="15">

      <RefinerName>write</RefinerName>

      <RefinementName>From 2010-11-11T07:18:13.4998560Z to 2010-11-11T18:49:08.4997920Z</RefinementName>

      <RefinementValue>[2010-11-11T07:18:13.4998560Z;2010-11-11T18:49:08.4997919Z]</RefinementValue>

      <RefinementToken>AREERnJvbSAyMDEwLTExLTExVDA3OjE4OjEzLjQ5OTg1Nj…==</RefinementToken>

      <RefinementCount>27</RefinementCount>

    </RefinementResults>

    <RefinementResults diffgr:id="RefinementResults17" msdata:rowOrder="16">

      <RefinerName>write</RefinerName>

      <RefinementName>From 2010-11-11T18:49:08.4997920Z to 2011-12-27T17:12:11.4998400Z</RefinementName>

      <RefinementValue>[2010-11-11T18:49:08.4997920Z;2011-12-27T17:12:11.4998399Z]</RefinementValue>

      <RefinementToken>AREERnJvbSAyMDEwLTExLTExVDE4OjQ5OjA4LjQ5OTc5MjBaIH…==</RefinementToken>

      <RefinementCount>19</RefinementCount>

    </RefinementResults>

    <RefinementResults diffgr:id="RefinementResults18" msdata:rowOrder="17">

      <RefinerName>write</RefinerName>

      <RefinementName>2011-12-27T17:12:11.4998400Z or later</RefinementName>

      <RefinementValue>[2011-12-27T17:12:11.4998400Z;]</RefinementValue>

      <RefinementToken>ARUCMjAxMS0xMi0yN1QxNzoxMjoxMS40OTk4NDAwWiBvciBsYXRlc…=</RefinementToken>

      <RefinementCount>22</RefinementCount>

    </RefinementResults>

    It gives you a few date ranges by default.  You have to carefully examine the values of RefinementName to figure it out, but effectively it comes down to documents from yesterday, documents in the last 6 weeks or so, and anything before that.  The refinement documentation on MSDN, seems to indicate that you can specify exact dates for it to refine on, but I haven’t fully explored it.

    Finally, we’ll talk about how Managed Metadata results get returned.  These come from the managed property, owsmetadatafacetinfo. 

    <RefinementResults diffgr:id="RefinementResults1" msdata:rowOrder="0">

      <RefinerName>owsmetadatafacetinfo</RefinerName>

      <RefinementName>CompanyName|CompanyName|SIY8F/QVWEiQVLpg6IwnCg==|SL8RuOhIpUekTSlmeLc0AQ==|#04cbd472-7446-45cd-87c3-57ea2e142888|Contoso;#</RefinementName>

      <RefinementValue>^CompanyName|CompanyName|SIY8F/QVWEiQVLpg6IwnCg==|SL8RuOhIpUekTSlmeLc0AQ==|#04cbd472-7446-45cd-87c3-57ea2e142888|Contoso;#$</RefinementValue>

      <RefinementToken>ARkHQ29tcGFueU5hbWV8Q29tcGFueU5hbWV8U0lZOEYvUVZXRWlRVkxwZzZJd25DZz09fFNMOFJ1T2hJcFVla1RTb…==</RefinementToken>

      <RefinementCount>19</RefinementCount>

    </RefinementResults>

    <RefinementResults diffgr:id="RefinementResults2" msdata:rowOrder="1">

      <RefinerName>owsmetadatafacetinfo</RefinerName>

      <RefinementName>ProductLine|ProductLine|SIY8F/QVWEiQVLpg6IwnCg==|HQGuvm9zUUGAE1lO7yojyA==|#5bff12c1-ed32-4e0e-aadb-f9bbdd436432|Office;#</RefinementName>

      <RefinementValue>^ProductLine|ProductLine|SIY8F/QVWEiQVLpg6IwnCg==|HQGuvm9zUUGAE1lO7yojyA==|#5bff12c1-ed32-4e0e-aadb-f9bbdd436432|Office;#$</RefinementValue>

      <RefinementToken>ARgHUHJvZHVjdExpbmV8UHJvZHVjdExpbmV8U0lZOEYvUVZXRWlRVkxwZzZJd25DZz09fEhRR3V2bTl6VVVHQUUxbE83e…Ek</RefinementToken>

      <RefinementCount>7</RefinementCount>

    </RefinementResults> 

    In this case, I have two managed metadata properties defined: CompanyName and ProductLine.  Actually, these names map back to underlying site columns.  In my case CompanyName is mapped to the built-in managed property Company.  The RefinementName element gives you a ton of date that you will have to parse through including the name of the site column, tokens, the GUID of the term and ultimately the text value.  Have fun parsing that. :)

    Now, that we have our refiners, we can use the RefinementToken to refine a subsequent query.  To do this, we just add a RefinementFilters element inside our Query element.  We include a RefinementFilter element with the token of each refiner we are using.  For example, to filter by Word documents from our previous results, we’ll add the values like this.

    <RefinementFilters>

      <RefinementFilter>AQ5NaWNyb3NvZnQgV29yZAZmb3JtYXQBAl4iAiIk</RefinementFilter>

    </RefinementFilters>

    You’ll get another set of results back like you did before only the results are now refined.  You can include multiple RefinementFilter elements if you want as well.  I know that’s a lot of XML for one post, but hopefully it’s useful.

  • How to: Query FAST Search for SharePoint with FQL and the Search Web Service

    I’ve written many posts on how to query search (Keyword in 2010, Keyword in 2007, QueryManager, Web Service, FQL using Keyword) and I wanted to keep up the tradition and talk about how easy it is to get started using FQL with the Search Web Service.  Our same techniques apply from my previous web service article with only some slight changes.  It may seem simple at first, but it’s the first building block that we need for a series of posts I am starting. 

    For today’s example, I am going to build off of the Silverlight 4 application I used at SPC.  I’m using Silverlight, but you could just as well write a console application or call this web service from some other ASP.NET application.  We still want to start by creating a service reference to /_vti_bin/search.asmx. We then create an instance of the web service so that we can use it.  We also bind an event handling method to handle the results of the web service call.

    QueryServiceSoapClient queryService = new QueryServiceSoapClient();

    queryService.QueryExCompleted += new EventHandler<QueryExCompletedEventArgs>(QueryService_QueryExCompleted);

    Once we have a reference to the web service, it’s just a matter of constructing the input XML document and sending it to the web service.  This input XML is typically the same for a basic query.  However, the difference here is in the type attribute of the QueryText element.  We want to specify a value of FQL instead of STRING.

    <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="FQL">productline:"*ice"</QueryText>

        </Context>

      </Query>

    </QueryPacket>

    That is what the XML looks like.  In this case, I am using a simple FQL query to return anything matching the managed property using a wildcard operator. In this case, I was looking for the word Office but you can see how I use “*ice” and still get results. This prefix wildcard operator only works with FQL. If you change the query back to type STRING (keyword), it would not work.  You can store it in a separate file or just build it with a StringBuilder.  We’ll go with a StringBuilder today for simplicity.

    queryXml.Append("<QueryPacket xmlns=\"urn:Microsoft.Search.Query\" Revision=\"1000\">");

    queryXml.Append("<Query domain=\"QDomain\">");

    queryXml.Append("<SupportedFormats>");

    queryXml.Append("<Format>");

    queryXml.Append("urn:Microsoft.Search.Response.Document.Document");

    queryXml.Append("</Format>");

    queryXml.Append("</SupportedFormats>");

    queryXml.Append("<Context>");

    queryXml.Append("<QueryText language=\"en-US\" type=\"FQL\">");

    queryXml.Append("productline:*ice");

    queryXml.Append("</QueryText>");

    queryXml.Append("</Context>");

    queryXml.Append("</Query>");

    queryXml.Append("</QueryPacket>");

    We then need to make the call to the Search web service.  Remember that you can call QueryEx to get a DataSet and Query to get an XML document.  I always prefer to work with the raw XML since I can use LINQ to XML with it.

    queryService.QueryExAsync(queryXml.ToString());

    We then jump implement our event handling method QueryService_QueryExCompleted.  Remember, that the XML we want is always in the node element in position 1.  We can bind this data to a textbox, like the snippet below or you can use my example from the SPC article to bind to a grid.

    ResultsTextBox.Text = e.Result.Nodes[1].ToString();

    Here is what my example looks like.

    FQLSilverlight4WebServiceResults

    As I said it’s pretty simple.  One thing I have noticed with the Silverlight application is that if you get the syntax of an FQL query wrong, it won’t return gracefully, it will throw a NotFound exception.  Who knows why?

    FQLSilverlight4NotFoundException

    In the above example, I didn’t specify the managed property with lower case letters.  It must be lower case or you will always get an exception.  This varies from the KeywordQuery syntax.  I hope this example helps.  Remember, if you do need help getting started with this application, take a look at the sample code I provided in the previous article.  In the following articles, I’ll start demonstrating how to leverage some of the more advanced FAST Search for SharePoint features using the web service.  I figured it would be good to write this article as a starting point first though.

  • Configuring Site Collection Search Settings with PowerShell

    I’m always looking for a way to automate things and configuring the search settings of a site collection is no exception.  I’ve talked about the Search Settings page before and how important it is for configuring contextual search and the scope drop down on your master page.  Wouldn’t it be nice to be able to automate these changes instead of having to manually set it on every site collection?

    To configure these settings, we first must understand where they are.  It turns out that they can be found in the AllProperties collection of the root SPWeb object in a site collection.  On a new site collection or on one where you have never configured the search settings, no values will exist in the property bag for search.  However, one you go to the search settings page and click save, it will write the values into the property bag.  As you may know, the search settings page has three configurable fields.  These values on the search settings page map to the values below in the property bag.

    Setting Property Bag Name
    Site Collection Search Center SRCH_ENH_FTR_URL
    Site Collection Search Dropdown Mode SRCH_SITE_DROPDOWN_MODE
    Site Collection Search Results Page SRCH_TRAGET_RESULTS_PAGE

    Now what goes in each value?  SRCH_ENH_FTR_URL typically takes a relative URL (i.e. /search/pages).  However, it can take full URL as well.  SRCH_SITE_DROPDOWN_MODE requires you pass a special string based upon what you want the drop down to display (i.e.: Show Scopes, Don’t Show Scopes, Default to s parameter, etc.)  How do you know what string to pass?  Well the easiest way to determine this is to go to the Search Settings page of the site collection and view source.  Search for the drop down mode you want and you will find the string in the value parameter of an option element.  Here is what it looks like.

    <option selected="selected" value="HideScopeDD_DefaultContextual">Do not show scopes
        dropdown, and default to contextual scope</option>
    <option value="HideScopeDD">Do not show scopes dropdown, and default to target results
        page</option>
    <option value="ShowDD">Show scopes dropdown</option>
    <option value="ShowDD_DefaultURL">Show, and default to 's' URL parameter</option>
    <option value="ShowDD_DefaultContextual">Show and default to contextual scope</option>
    <option value="ShowDD_NoContextual">Show, do not include contextual scopes</option>
    <option value="ShowDD_NoContextual_DefaultURL">Show, do not include contextual scopes,
        and default to 's' URL parameter</option>

    For example, I typically use the option Show and default to contextual scope, so I would choose ShowDD_DefaultContextual

    The last value, SRCH_TRAGET_RESULTS_PAGE cracks me up.  Note how the word target is misspelled.  It looks like something slipped past QA there.  This value specifies the URL to the contextual search page.  Typically, I change this to use the URL to my search center as I have mentioned before.  Anyhow, if you want to set this value be sure and misspell it.

    Now that we know what values we need to set, how do we put it all together with PowerShell?  It’s pretty simple.  First we need access to the SPWeb object of the root web of the site collection we want to change.  You can use Get-SPSite first to do this, but if you know the URL, then you can just use Get-SPWeb.  Either way you do it, get yourself an SPWeb object.  Here is an example:

    $web = Get-SPWeb http://server/sitecollection

    If you have the right permissions, you should get a blank prompt back without error.  If you get an access denied error, then you need to go make use of Add-SPShellAdmin

    Now that you have the SPWeb object, you can see if any values have been set for search by using the AllProperties collection.

    $web.AllProperties

    SearchSettingsPowerShellAllProperties

    In my case, no properties have been set yet.  Now I can set my values.  You can set one or more of these in your script.

    $web.AllProperties["SRCH_ENH_FTR_URL"] = "/search/pages";
    $web.AllProperties["SRCH_SITE_DROPDOWN_MODE"] = "ShowDD_DefaultContextual";
    $web.AllProperties["SRCH_TRAGET_RESULTS_PAGE"] = "http://server/search/pages/results.aspx";

    After you set your values, don’t forget to call .Update() just like you would when working directly with the object model.

    $web.Update();

    Executing the script should just return you to the PowerShell prompt if everything worked.  You can verify your settings, by looking in the AllProperties collection.  For example.  Just make sure you get a new instance of the SPWeb object first or you won’t see the changes.

    $web = Get-SPWeb http://server/sitecollection
    $web.AllProperties["SRCH_ENH_FTR_URL"]

    SearchSettingsPowerShellPropertySet

    As you can see it’s really simple.  Now what if you wanted to set these settings on all site collections?

    $webApp = Get-SPWebApplication http://server;
    $siteCollections = $webApp | Get-SPSite –limit all;
    $siteCollections | ForEach-Object {
    $web = $_.RootWeb
    $web.AllProperties["SRCH_ENH_FTR_URL"] = "/search/pages";
    $web.AllProperties["SRCH_SITE_DROPDOWN_MODE"] = "ShowDD_DefaultContextual";
    $web.AllProperties["SRCH_TRAGET_RESULTS_PAGE"] = "http://server/search/pages/results.aspx";
    $web.Update();
    }

    Try that out and see if that works for you. 

  • Using search to find recently modified files in SharePoint 2010

    Last week, I posted about how we can extend CoreResultsWebPart to show documents created by the current user.  Using this same technique, we can also use search to find recently modified documents.  If you are a long time follower of my blog, you might remember that I posted how to do with using the Wildcard Search Web Part in SharePoint 2007.  In an effort to keep posts updated, I thought I would post a follow up on how we can do the same thing in SharePoint 2010.  Since the CoreResultWebPart has changed quite a bit, the solution is quite a bit cleaner and still only requires two lines of code.  Again, we are going to create a web part that inherits from CoreResultsWebPart as described in my Wildcard Search Web Part for SharePoint 2010 post. 

    The first thing we need to do is change the QueryNumber.  By default it is set to Query1 (or UserQuery back in 2007) which meant that it was expecting input from the user.  In this case, I just change it to Query2.

    this.QueryNumber = QueryId.Query2;

    Then we just need to construct a query using the Write keyword.  I’ve explained its use before in my handy keywords post.  It’s syntax is usually something like this.  Note that there are no spaces anywhere in the string below.

    Write>=”12/1/2011”

    Of course this would hard code the date and we don’t want that.  So what I do instead is use DateAdd and subtract a number of days.  In my case, I want to show all documents from the last seven days.  We assign this query to the FixedQuery property.  Here is what it looks like.

    this.FixedQuery = string.Format("Write>=\"{0}\"", DateTime.Today.AddDays(-7));

    Compile your code and deploy it and then you are good to go.  Just use this web part in lieu of the regularCoreResultsWebPart.  Here’s what it looks like on my page.

    SearchRecentDocuments

    That’s all there is to it.  One addition, you might want to make to your code is to allow the number of days to be user configurable.  You can easily make a web part property that allows the user to specify the number of days.

  • Using SharePoint Search to display the documents of the current user

    I see requests for this in the SharePoint forums a lot and I always figured it was pretty easy to do with a few lines of code.  Sometimes users want to display a list of documents that the worked on throughout the farm.  The CoreResultsWebPart has the ability to execute fixed static queries.  However, there is no way for you to specify the current user in the query.  I had a need for this myself soon so I thought I would try it out and see if I could implement it.  It turns our this can be done with two lines of code.

    To implement this we need to create a class that inherits from CoreResultsWebPart.  I am doing this in the exact same way I built the Wildcard Search Web Part for SharePoint 2010.  You can download that web part from CodePlex if you want to use it as a starting point.  What we want to do is set the FixedQuery property.  Normally when we do query manipulation, we do it after it has been submitted by the user with GetXPathNavigator().  We don’t need to override that method in this case.  Instead, I just put the code I need in the constructor.

    The first thing we need to do is change the QueryNumber.  By default it is set to Query1 (or UserQuery back in 2007) which meant that it was expecting input from the user.  In this case, I just change it to Query2.

    this.QueryNumber = QueryId.Query2;

    Next, we write a query using the Author keyword.  I’ve explained its use before in my handy keywords post.  It’s syntax is usually something like this.

    Author:”Display Name”

    So for example, to search for my documents I would use:

    Author:”Corey Roth”

    We want to put the user’s name in the Author query dynamically, so we look it up using SPContext.Current.Web.UserQuery.  We then just use the keyword syntax above and assign it to the FixedQuery property.

    this.FixedQuery = string.Format("Author:\"{0}\"", SPContext.Current.Web.CurrentUser.Name);

    Compile your code and deploy it and then you are good to go.  Just use this web part in lieu of the regular CoreResultsWebPart.  Here’s what it looks like on my page.

    SearchMyDocuments

    Try it out and let me know if you have any questions.

    @coreyroth

2015 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems