views:

1757

answers:

2

So our scenario is this: We have multiple Sharepoint sites that are created dynamically on a "as requested" basis. Basically there's a new site for each new project. Now, for every site we want to add a search clause that says that only contents with a metadata tag value equal to the sitename should be found. Quick example: There are 2 sites/projects: Bear and Wolf. Sharepoint Search has index all of the documents/lists/etc from these sites and a common archive for them. All documents in the common archive has a property called "ProjectName". When Bill, who's on the Wolf team, wants to search for "specifications" in his project site (Wolf) he only wants to see documents relevant to that project. So how do I make sure that all the documents have the "ProjectName" value set to "Wolf"?

I'm guessing I could use Scopes here, but currently there are ~200 sites and this is growing every month and so maintaining that manually is not an option. If there's a relativly easy way of automating Scopes; excellent.

+1  A: 

Search scopes are pretty easy to manage programatically. See here.

I have done this when search scopes needed to be released as part of a feature.

Works fine.

Below, code lifted from MS article above.

private ServerContext serverctx = null;
private SearchContext searchctx = null;
serverctx = ServerContext.GetContext("SharedServices1");
searchctx = SearchContext.GetContext(serverctx);
Scopes scopes = new Scopes(searchctx);
foreach (Scope scope in scopes.GetSharedScopes())

TreeNode node = treeViewScopes.Nodes.Add(scope.Name);

foreach (TreeNode node in treeViewScopes.Nodes)
{
  foreach (ScopeRule rule in scope.Rules)
  {
    if (rule is PropertyQueryScopeRule)
    {
      PropertyQueryScopeRule prule = (PropertyQueryScopeRule)rule;
      TreeNode childnode = node.Nodes.Add("Property Query Rule: ");
      childnode.Text += prule.Property.Name + " =  " + prule.Value;
    }
    if (rule is AllContentScopeRule)
    {
      AllContentScopeRule arule = (AllContentScopeRule)rule;
      node.Nodes.Add("All Content Rule");
    }
    if (rule is UrlScopeRule)
    {
      UrlScopeRule urule = (UrlScopeRule)rule;
      TreeNode childnode = node.Nodes.Add("URL Rule: ");
      childnode.Text += urule.MatchingString;
    }
  }
}

UPDATE

I would add a property to each site and use that property to determine which scope each web needed to be added to. A console style app could then go through each web on the server and add scope rules to add each url to the correct scope or not.

That would allow documents to be added to site without having to explicitly set a document level "project" property, ensuring documents were not left out of the search within a particular scope.

Another solution to this is to iterate through each document, add a field if not already there that specifies the project name and set that project name on the document if it does not match the property of the site. Could end up being a long running task. Much better to use the search scope I would think.

Nat
The problem with this approach, I believe, is that our scope is OR scope. So basically we want to search for all documents where the property "ProjectName" == Wolf or where this property is not present. With a scope we could limit it to "ProjectName == Wolf", but that would exclude a lot of docs...
noocyte
+1  A: 

While you could use scopes for this, I would not recommend it. The href field will give you everything you need to fully automate the search with no ongoing maintenance burden.

You can execute a search and filter out all of the items outside of the selected site based on the site URL as a required prefix for any items returned. This works because e.g. given a site at http://server/bears, the URLs for all of the items within the site will be of the form http://server/bears/....

Jason Weber
Unfortunately we have a source outside of Sharepoint (Meridio actually), so the URLs can't be used as a filter... Looks like we'll be adding query terms directly...
noocyte
Can you could enforce the convention that e.g. the ProjectName tag value in Meridio must match the site portion of the project site's URL? If so the search query is a little more complex but can once again be automated.
Jason Weber