Skip to content
This repository was archived by the owner on Jan 19, 2021. It is now read-only.

Commit 0f89424

Browse files
Merge pull request #2855 from pnp/search-improvments
Improve -All queries.
2 parents 80f4951 + 0297c32 commit 0f89424

File tree

3 files changed

+66
-68
lines changed

3 files changed

+66
-68
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
1515
- Fixed issue with Submit-PnPTeamsChannelMessage not posting HTML message when setting the content type to Html.
1616
- The content type that Submit-PnPTeamsChannelMessage uses defaults now to HTML.
1717
- Fixed an issue with the PnP Provisioning Engine not being able to correctly acquire a token for the Microsoft Graph when provisioning a tenant template containing a Team.
18+
- Optimized Submit-PnPSearchQuery and Get-PnPSiteSearchQueryResults cmdlets when using the -All parameter.
19+
- Fixed TrimDuplicates to be default off for Submit-PnPSearchQuery
1820

1921
### Contributors
2022

Lines changed: 26 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
using System.Management.Automation;
2-
using Microsoft.SharePoint.Client;
3-
using Microsoft.SharePoint.Client.Search.Query;
42
using PnP.PowerShell.CmdletHelpAttributes;
53
using System.Collections.Generic;
6-
using System.Linq;
74

85
namespace PnP.PowerShell.Commands.Search
96
{
@@ -52,68 +49,40 @@ public class GetSiteSearchQueryResults : PnPWebCmdlet
5249

5350
protected override void ExecuteCmdlet()
5451
{
55-
int startRow = StartRow;
56-
int rowLimit = MaxResults;
57-
if (All.IsPresent)
52+
var queryCmdLet = new SubmitSearchQuery();
53+
queryCmdLet.StartRow = StartRow;
54+
queryCmdLet.MaxResults = MaxResults;
55+
var query = "contentclass:STS_Site";
56+
if (!string.IsNullOrEmpty(Query))
5857
{
59-
startRow = 0;
60-
rowLimit = 500;
58+
query = query + " AND " + Query;
6159
}
62-
int currentCount = 0;
63-
var dynamicList = new List<dynamic>();
64-
do
65-
{
66-
var keywordQuery = GetKeywordQuery();
67-
keywordQuery.StartRow = startRow;
68-
keywordQuery.RowLimit = rowLimit;
60+
queryCmdLet.Query = query;
6961

70-
var searchExec = new SearchExecutor(ClientContext);
71-
var results = searchExec.ExecuteQuery(keywordQuery);
72-
ClientContext.ExecuteQueryRetry();
73-
74-
if (results?.Value[0].RowCount > 0)
75-
{
76-
var result = results.Value[0];
77-
currentCount = result.ResultRows.Count();
78-
79-
foreach (var row in result.ResultRows)
80-
{
81-
dynamicList.Add(
82-
new
83-
{
84-
Title = row["Title"]?.ToString() ?? "",
85-
Url = row["SPSiteUrl"]?.ToString() ?? "",
86-
Description = row["Description"]?.ToString() ?? "",
87-
WebTemplate = row["WebTemplate"]?.ToString() ?? ""
88-
});
89-
}
90-
}
91-
startRow += rowLimit;
92-
93-
} while (currentCount == rowLimit && All.IsPresent);
94-
WriteObject(dynamicList, true);
95-
}
62+
queryCmdLet.SelectProperties = new[] {"Title","SPSiteUrl","Description","WebTemplate"};
63+
queryCmdLet.SortList = new System.Collections.Hashtable
64+
{
65+
{ "SPSiteUrl", "ascending" }
66+
};
67+
queryCmdLet.RelevantResults = true;
9668

97-
private KeywordQuery GetKeywordQuery()
98-
{
99-
var keywordQuery = new KeywordQuery(ClientContext);
69+
var res = queryCmdLet.Run();
10070

101-
// Construct query to execute
102-
var query = "contentclass:STS_Site";
103-
if (!string.IsNullOrEmpty(Query))
71+
var dynamicList = new List<dynamic>();
72+
foreach (var row in res)
10473
{
105-
query = query + " AND " + Query;
74+
var obj = row as PSObject;
75+
dynamicList.Add(
76+
new
77+
{
78+
Title = obj.Properties["Title"]?.Value ?? "",
79+
Url = obj.Properties["SPSiteUrl"]?.Value ?? "",
80+
Description = obj.Properties["Description"]?.Value ?? "",
81+
WebTemplate = obj.Properties["WebTemplate"]?.Value ?? ""
82+
});
10683
}
10784

108-
keywordQuery.QueryText = query;
109-
keywordQuery.SelectProperties.Add("Title");
110-
keywordQuery.SelectProperties.Add("SPSiteUrl");
111-
keywordQuery.SelectProperties.Add("Description");
112-
keywordQuery.SelectProperties.Add("WebTemplate");
113-
keywordQuery.SortList.Add("SPSiteUrl", SortDirection.Ascending);
114-
// Important to avoid trimming "similar" site collections
115-
keywordQuery.TrimDuplicates = false;
116-
return keywordQuery;
85+
WriteObject(dynamicList, true);
11786
}
11887
}
11988
}

Commands/Search/SubmitSearchQuery.cs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,34 +105,43 @@ public class SubmitSearchQuery : PnPWebCmdlet
105105
[Parameter(Mandatory = false, HelpMessage = "Specifies whether only relevant results are returned", ParameterSetName = ParameterAttribute.AllParameterSets)]
106106
public SwitchParameter RelevantResults;
107107

108-
protected override void ExecuteCmdlet()
108+
internal IEnumerable<object> Run()
109109
{
110110
int startRow = StartRow;
111111
int rowLimit = MaxResults;
112+
// Used for internal Microsoft telemetry
113+
string clientFunction = "Search";
112114
if (All.IsPresent)
113115
{
116+
clientFunction = "Scanner";
114117
startRow = 0;
115118
rowLimit = 500;
116119
SortList = new Hashtable()
117120
{
118-
{"IndexDocId", "ascending"}
121+
{"[DocId]", "ascending"} // Special optimized sorting when iterating all items
119122
};
120123
}
121124

122125
var currentCount = 0;
126+
string lastDocId = "0";
123127
PnPResultTableCollection finalResults = null;
124128
do
125129
{
126-
KeywordQuery keywordQuery = CreateKeywordQuery();
130+
KeywordQuery keywordQuery = CreateKeywordQuery(clientFunction);
127131
keywordQuery.StartRow = startRow;
128132
keywordQuery.RowLimit = rowLimit;
129133

130-
var searchExec = new SearchExecutor(ClientContext);
131-
if (startRow > 0 && All.IsPresent)
134+
if (All.IsPresent)
132135
{
133-
keywordQuery.Refiners = null; // Only need to set on first page for auto paging
136+
if (currentCount != 0)
137+
{
138+
keywordQuery.Refiners = null; // Only need to set on first page for auto paging
139+
}
140+
keywordQuery.StartRow = 0;
141+
keywordQuery.QueryText += " IndexDocId>" + lastDocId;
134142
}
135143

144+
var searchExec = new SearchExecutor(ClientContext);
136145
var results = searchExec.ExecuteQuery(keywordQuery);
137146
ClientContext.ExecuteQueryRetry();
138147

@@ -146,6 +155,7 @@ protected override void ExecuteCmdlet()
146155
if (resultTable.TableType == "RelevantResults")
147156
{
148157
currentCount = resultTable.RowCount;
158+
lastDocId = resultTable.ResultRows.Last()["DocId"].ToString();
149159
}
150160
}
151161
}
@@ -167,25 +177,36 @@ protected override void ExecuteCmdlet()
167177
if (pnpResultTable.TableType == "RelevantResults")
168178
{
169179
currentCount = resultTable.RowCount;
180+
if (currentCount > 0)
181+
{
182+
lastDocId = resultTable.ResultRows.Last()["DocId"].ToString();
183+
}
170184
}
171185
}
172186
}
173187

174188
}
175189
startRow += rowLimit;
176190
} while (currentCount == rowLimit && All.IsPresent);
191+
177192
if (!RelevantResults.IsPresent)
178193
{
179-
WriteObject(finalResults, true);
194+
return finalResults;
180195
}
181196
else
182197
{
183198
var results = finalResults.FirstOrDefault(t => t.TableType == "RelevantResults")?
184199
.ResultRows.Select(r => ConvertToPSObject(r));
185-
WriteObject(results, true);
200+
return results;
186201
}
187202
}
188203

204+
protected override void ExecuteCmdlet()
205+
{
206+
var results = Run();
207+
WriteObject(results, true);
208+
}
209+
189210
private object ConvertToPSObject(IDictionary<string, object> r)
190211
{
191212
PSObject res = new PSObject();
@@ -199,7 +220,7 @@ private object ConvertToPSObject(IDictionary<string, object> r)
199220
return res;
200221
}
201222

202-
private KeywordQuery CreateKeywordQuery()
223+
private KeywordQuery CreateKeywordQuery(string clientFunction)
203224
{
204225
var keywordQuery = new KeywordQuery(ClientContext);
205226

@@ -212,7 +233,7 @@ private KeywordQuery CreateKeywordQuery()
212233

213234
keywordQuery.QueryText = query;
214235
keywordQuery.ClientType = ClientType;
215-
if (ParameterSpecified(nameof(TrimDuplicates))) keywordQuery.TrimDuplicates = TrimDuplicates;
236+
keywordQuery.TrimDuplicates = TrimDuplicates;
216237
if (ParameterSpecified(nameof(Refiners))) keywordQuery.Refiners = Refiners;
217238
if (ParameterSpecified(nameof(Culture))) keywordQuery.Culture = Culture;
218239
if (ParameterSpecified(nameof(QueryTemplate))) keywordQuery.QueryTemplate = QueryTemplate;
@@ -245,7 +266,7 @@ private KeywordQuery CreateKeywordQuery()
245266
{
246267
SelectProperties = SelectProperties[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
247268
}
248-
269+
249270
foreach (string property in SelectProperties)
250271
{
251272
selectProperties.Add(property.Trim());
@@ -289,6 +310,12 @@ private KeywordQuery CreateKeywordQuery()
289310
keywordQuery.Properties.SetQueryPropertyValue(key, propVal);
290311
}
291312
}
313+
314+
QueryPropertyValue clientFuncPropVal = new QueryPropertyValue();
315+
clientFuncPropVal.StrVal = clientFunction;
316+
clientFuncPropVal.QueryPropertyValueTypeIndex = 1;
317+
318+
keywordQuery.Properties.SetQueryPropertyValue("ClientFunction", clientFuncPropVal);
292319
return keywordQuery;
293320
}
294321
}

0 commit comments

Comments
 (0)