locked
KeywordQuery PS script returning less results than SharePoint search RRS feed

  • Question

  • Hello there,

    I'm using a powershell script to search into a SiteCollection for a certain keyword and download the results to a local folder. The script runs well, but it's returning less results than the standard search on SharePoint portal. I don't know why this is happening, in theory it should be the same, but with the script I'm getting 40 results (for example) and in the search site there are like 120 results.

    This is script I'm using:

    param([string]$url,[string]$keyword,[string]$path)
    
    if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) 
    {
         Add-PSSnapin Microsoft.SharePoint.PowerShell;
    }
    
    # setup a keyword query object
    Function SearchForDocs ([string]$url,[string]$keyword,[string]$path)
    {
    	$site = new-object microsoft.sharepoint.spsite $url
    	$kq = new-object microsoft.office.server.search.query.keywordquery $site
    	
    	# $web = Get-SPWeb -Identity $url
    	# $kq = New-Object Microsoft.office.Server.Search.Query.KeywordQuery $web
    	
    	# set some query properties...
    	$kq.ResultTypes = [Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults
    	$kq.QueryText = $keyword
    	  
    	# issue the query...
    	$resultTableCollection = $kq.Execute()
    	 
    	# get the result table...
    	$relResultTable = $resultTableCollection.Item([Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults)
    	$relDataTable = $relResultTable.Table
    	 
    	# and output the results
    	$tocopydocx = $relDataTable.Rows
    	 
    	$wc = New-Object System.Net.WebClient
    	# The next 5 lines are required if your network has a proxy server
    	$wc.Credentials = [System.Net.CredentialCache]::DefaultCredentials
    	if($wc.Proxy -ne $null)
    	{
    		$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
    	}
     
    	foreach ($File in $tocopydocx) 
    	{
    		if ($File.Path -ne $null)
    		{
    			$filename = $File.Path.split("/") | Select-Object -Last 1
    			# write-host $filename -ForegroundColor Yellow
    	    	$wc.DownloadFile($File.Path, $path+"\"+ $filename)
    		}
    	}
    }
    
    SearchForDocs $url $keyword $path
    

    Anyone can help me understand why I'm getting less results than expected?

    Thank you!

    Thursday, August 8, 2013 11:02 AM

Answers

  • SHAME ON ME!

    I found that two things are wrong in the script!

    First of all, when you set no row limit to the search engine, it gets it's default value to 50! Beautiful! So you have to set the RowLimit to 1000 in order to get as many results as possible.

    The other thing I also noticed is that some documents have the exactly same name, and when they are being downloaded to the local folder they are overwritten each time the same document is found. So I used a workaround on naming the documents and I used the whole url of the document and parsed the unwanted characters.

    Finally the script looks like this:

    param([string]$url,[string]$keyword,[string]$path)
    
    if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) 
    {
         Add-PSSnapin Microsoft.SharePoint.PowerShell;
    }
    
    # setup a keyword query object
    Function SearchForDocs ([string]$url,[string]$keyword,[string]$path)
    {
    	$site = new-object microsoft.sharepoint.spsite $url
    	$kq = new-object microsoft.office.server.search.query.keywordquery $site
    	
    	# $web = Get-SPWeb -Identity $url
    	# $kq = New-Object Microsoft.office.Server.Search.Query.KeywordQuery $web
    	
    	# set some query properties...
    	$kq.ResultTypes = [Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults
    	$kq.QueryText = $keyword
    	$kq.RowLimit = 1000
    	  
    	# issue the query...
    	$resultTableCollection = $kq.Execute()
    	 
    	# get the result table...
    	$relResultTable = $resultTableCollection.Item([Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults)
    	$relDataTable = $relResultTable.Table
    	 
    	# and output the results
    	$tocopydocx = $relDataTable.Rows
    	 
    	$wc = New-Object System.Net.WebClient
    	# The next 5 lines are required if your network has a proxy server
    	$wc.Credentials = [System.Net.CredentialCache]::DefaultCredentials
    	if($wc.Proxy -ne $null)
    	{
    		$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
    	}
     	
    	write-host $tocopydocx.Count
    
    	foreach ($File in $tocopydocx) 
    	{
    		if ($File.Path -ne $null)
    		{
    			# $filename = $File.Path.split("/") | Select-Object -Last 1
    			$filename = $File.Path -replace "/", "_"
    			$filename = $filename -replace ":", ""
    			# write-host $filename -ForegroundColor Yellow
    	    	$wc.DownloadFile($File.Path, $path+"\"+ $filename)
    		}
    	}
    }
    
    SearchForDocs $url $keyword $path

    Hope it helps!

    • Marked as answer by Marc Jordana Thursday, August 8, 2013 12:25 PM
    Thursday, August 8, 2013 12:24 PM

All replies

  • Are you sure they are not being security trimmed?  Are you using the same account on the server as you are in the browser?

    Brandon Atkinson
    Blog: http://brandonatkinson.blogspot.com

    Thursday, August 8, 2013 11:11 AM
  • Yes, I'm using my AD user to access both, and I'm set as Farm and Server admin.
    Thursday, August 8, 2013 11:23 AM
  • Can you post what you are passing in as a search parameter?

    Brandon Atkinson
    Blog: http://brandonatkinson.blogspot.com

    Thursday, August 8, 2013 11:29 AM
  • This is the search I'm doing in the search site in SharePoint in the scope of the site http://kms:83

    And this is the call to the script from powershell

    50 is the results found with the script.

    Thursday, August 8, 2013 11:43 AM
  • SHAME ON ME!

    I found that two things are wrong in the script!

    First of all, when you set no row limit to the search engine, it gets it's default value to 50! Beautiful! So you have to set the RowLimit to 1000 in order to get as many results as possible.

    The other thing I also noticed is that some documents have the exactly same name, and when they are being downloaded to the local folder they are overwritten each time the same document is found. So I used a workaround on naming the documents and I used the whole url of the document and parsed the unwanted characters.

    Finally the script looks like this:

    param([string]$url,[string]$keyword,[string]$path)
    
    if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) 
    {
         Add-PSSnapin Microsoft.SharePoint.PowerShell;
    }
    
    # setup a keyword query object
    Function SearchForDocs ([string]$url,[string]$keyword,[string]$path)
    {
    	$site = new-object microsoft.sharepoint.spsite $url
    	$kq = new-object microsoft.office.server.search.query.keywordquery $site
    	
    	# $web = Get-SPWeb -Identity $url
    	# $kq = New-Object Microsoft.office.Server.Search.Query.KeywordQuery $web
    	
    	# set some query properties...
    	$kq.ResultTypes = [Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults
    	$kq.QueryText = $keyword
    	$kq.RowLimit = 1000
    	  
    	# issue the query...
    	$resultTableCollection = $kq.Execute()
    	 
    	# get the result table...
    	$relResultTable = $resultTableCollection.Item([Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults)
    	$relDataTable = $relResultTable.Table
    	 
    	# and output the results
    	$tocopydocx = $relDataTable.Rows
    	 
    	$wc = New-Object System.Net.WebClient
    	# The next 5 lines are required if your network has a proxy server
    	$wc.Credentials = [System.Net.CredentialCache]::DefaultCredentials
    	if($wc.Proxy -ne $null)
    	{
    		$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
    	}
     	
    	write-host $tocopydocx.Count
    
    	foreach ($File in $tocopydocx) 
    	{
    		if ($File.Path -ne $null)
    		{
    			# $filename = $File.Path.split("/") | Select-Object -Last 1
    			$filename = $File.Path -replace "/", "_"
    			$filename = $filename -replace ":", ""
    			# write-host $filename -ForegroundColor Yellow
    	    	$wc.DownloadFile($File.Path, $path+"\"+ $filename)
    		}
    	}
    }
    
    SearchForDocs $url $keyword $path

    Hope it helps!

    • Marked as answer by Marc Jordana Thursday, August 8, 2013 12:25 PM
    Thursday, August 8, 2013 12:24 PM