@pnp/cli-microsoft365 7.5.0-beta.940b241 → 7.5.0-beta.c0c1edf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -38,16 +38,15 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
38
38
|
if (this.verbose) {
|
|
39
39
|
await logger.logToStderr(`Executing search query '${args.options.queryText}' on site at ${webUrl}...`);
|
|
40
40
|
}
|
|
41
|
-
const
|
|
42
|
-
const results = await this.executeSearchQuery(logger, args, webUrl, [], startRow);
|
|
41
|
+
const results = await this.executeSearchQuery(logger, args, webUrl, []);
|
|
43
42
|
this.printResults(logger, args, results);
|
|
44
43
|
}
|
|
45
44
|
catch (err) {
|
|
46
45
|
this.handleRejectedODataJsonPromise(err);
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
|
-
async executeSearchQuery(logger, args, webUrl, resultSet,
|
|
50
|
-
const requestUrl = await this.getRequestUrl(webUrl, logger, args,
|
|
48
|
+
async executeSearchQuery(logger, args, webUrl, resultSet, lastDocId = '0') {
|
|
49
|
+
const requestUrl = await this.getRequestUrl(webUrl, logger, args, lastDocId);
|
|
51
50
|
const requestOptions = {
|
|
52
51
|
url: requestUrl,
|
|
53
52
|
headers: {
|
|
@@ -57,26 +56,36 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
57
56
|
};
|
|
58
57
|
const searchResult = await request.get(requestOptions);
|
|
59
58
|
resultSet.push(searchResult);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const rowLimit = args.options.rowLimit ? args.options.rowLimit : 500;
|
|
60
|
+
if (args.options.allResults && searchResult.PrimaryQueryResult.RelevantResults.RowCount === rowLimit) {
|
|
61
|
+
if (this.verbose) {
|
|
62
|
+
await logger.logToStderr(`Processing search query, retrieved ${resultSet.length * searchResult.PrimaryQueryResult.RelevantResults.RowCount} of ${resultSet[0].PrimaryQueryResult.RelevantResults.TotalRows} items...`);
|
|
63
|
+
}
|
|
64
|
+
// When running in allResults mode, paging is done using the DocId property
|
|
65
|
+
// This is a more stable way than using the StartRow property.
|
|
66
|
+
// Explanation: https://learn.microsoft.com/sharepoint/dev/general-development/pagination-for-large-result-sets
|
|
67
|
+
const lastRow = searchResult.PrimaryQueryResult.RelevantResults.Table.Rows[searchResult.PrimaryQueryResult.RelevantResults.RowCount - 1];
|
|
68
|
+
const newLastDocId = lastRow.Cells.filter(cell => cell.Key === 'DocId')[0].Value;
|
|
69
|
+
return this.executeSearchQuery(logger, args, webUrl, resultSet, newLastDocId);
|
|
63
70
|
}
|
|
64
71
|
return resultSet;
|
|
65
72
|
}
|
|
66
|
-
async getRequestUrl(webUrl, logger, args,
|
|
73
|
+
async getRequestUrl(webUrl, logger, args, lastDocId) {
|
|
67
74
|
// get the list of selected properties
|
|
68
75
|
const selectPropertiesArray = this.getSelectPropertiesArray(args);
|
|
76
|
+
// get the sort list
|
|
77
|
+
const sortList = this.getSortList(args);
|
|
69
78
|
// transform arg data to query string parameters
|
|
70
|
-
const propertySelectRequestString = `&selectproperties='${formatting.encodeQueryParameter(selectPropertiesArray.join(
|
|
71
|
-
const startRowRequestString = `&startrow=${startRow ? startRow : 0}`;
|
|
72
|
-
const rowLimitRequestString = args.options.rowLimit ? `&rowlimit=${args.options.rowLimit}` :
|
|
79
|
+
const propertySelectRequestString = `&selectproperties='${formatting.encodeQueryParameter(selectPropertiesArray.join(','))}'`;
|
|
80
|
+
const startRowRequestString = `&startrow=${args.options.startRow ? args.options.startRow : 0}`;
|
|
81
|
+
const rowLimitRequestString = args.options.rowLimit ? `&rowlimit=${args.options.rowLimit}` : (args.options.allResults ? `&rowlimit=500` : '');
|
|
73
82
|
const sourceIdRequestString = args.options.sourceId ? `&sourceid='${args.options.sourceId}'` : ``;
|
|
74
|
-
const trimDuplicatesRequestString = `&trimduplicates=${args.options.trimDuplicates ? args.options.trimDuplicates :
|
|
75
|
-
const enableStemmingRequestString = `&enablestemming=${typeof (args.options.enableStemming) === 'undefined' ?
|
|
83
|
+
const trimDuplicatesRequestString = `&trimduplicates=${args.options.trimDuplicates ? args.options.trimDuplicates : 'false'}`;
|
|
84
|
+
const enableStemmingRequestString = `&enablestemming=${typeof (args.options.enableStemming) === 'undefined' ? 'true' : args.options.enableStemming}`;
|
|
76
85
|
const cultureRequestString = args.options.culture ? `&culture=${args.options.culture}` : ``;
|
|
77
86
|
const refinementFiltersRequestString = args.options.refinementFilters ? `&refinementfilters='${args.options.refinementFilters}'` : ``;
|
|
78
87
|
const queryTemplateRequestString = args.options.queryTemplate ? `&querytemplate='${args.options.queryTemplate}'` : ``;
|
|
79
|
-
const sortListRequestString =
|
|
88
|
+
const sortListRequestString = sortList ? `&sortList='${sortList}'` : ``;
|
|
80
89
|
const rankingModelIdRequestString = args.options.rankingModelId ? `&rankingmodelid='${args.options.rankingModelId}'` : ``;
|
|
81
90
|
const propertiesRequestString = this.getPropertiesRequestString(args);
|
|
82
91
|
const refinersRequestString = args.options.refiners ? `&refiners='${args.options.refiners}'` : ``;
|
|
@@ -86,8 +95,9 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
86
95
|
const processBestBetsRequestString = typeof (args.options.processBestBets) === 'undefined' ? `` : `&processbestbets=${args.options.processBestBets}`;
|
|
87
96
|
const enableQueryRulesRequestString = typeof (args.options.enableQueryRules) === 'undefined' ? `` : `&enablequeryrules=${args.options.enableQueryRules}`;
|
|
88
97
|
const processPersonalFavoritesRequestString = typeof (args.options.processPersonalFavorites) === 'undefined' ? `` : `&processpersonalfavorites=${args.options.processPersonalFavorites}`;
|
|
98
|
+
const indexDocIdQueryText = args.options.allResults ? ` IndexDocId>${lastDocId}` : '';
|
|
89
99
|
// construct single requestUrl
|
|
90
|
-
const requestUrl = `${webUrl}/_api/search/query?querytext='${args.options.queryText}'`.concat(propertySelectRequestString, startRowRequestString, rowLimitRequestString, sourceIdRequestString, trimDuplicatesRequestString, enableStemmingRequestString, cultureRequestString, refinementFiltersRequestString, queryTemplateRequestString, sortListRequestString, rankingModelIdRequestString, propertiesRequestString, refinersRequestString, hiddenConstraintsRequestString, clientTypeRequestString, enablePhoneticRequestString, processBestBetsRequestString, enableQueryRulesRequestString, processPersonalFavoritesRequestString);
|
|
100
|
+
const requestUrl = `${webUrl}/_api/search/query?querytext='${args.options.queryText}${indexDocIdQueryText}'`.concat(propertySelectRequestString, startRowRequestString, rowLimitRequestString, sourceIdRequestString, trimDuplicatesRequestString, enableStemmingRequestString, cultureRequestString, refinementFiltersRequestString, queryTemplateRequestString, sortListRequestString, rankingModelIdRequestString, propertiesRequestString, refinersRequestString, hiddenConstraintsRequestString, clientTypeRequestString, enablePhoneticRequestString, processBestBetsRequestString, enableQueryRulesRequestString, processPersonalFavoritesRequestString);
|
|
91
101
|
if (this.debug) {
|
|
92
102
|
await logger.logToStderr(`RequestURL: ${requestUrl}`);
|
|
93
103
|
}
|
|
@@ -96,7 +106,7 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
96
106
|
getPropertiesRequestString(args) {
|
|
97
107
|
let properties = args.options.properties ? args.options.properties : '';
|
|
98
108
|
if (args.options.sourceName) {
|
|
99
|
-
if (properties && !properties.endsWith(
|
|
109
|
+
if (properties && !properties.endsWith(',')) {
|
|
100
110
|
properties += `,`;
|
|
101
111
|
}
|
|
102
112
|
properties += `SourceName:${args.options.sourceName},SourceLevel:SPSite`;
|
|
@@ -104,9 +114,26 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
104
114
|
return properties ? `&properties='${properties}'` : ``;
|
|
105
115
|
}
|
|
106
116
|
getSelectPropertiesArray(args) {
|
|
107
|
-
|
|
108
|
-
? args.options.selectProperties.split(
|
|
109
|
-
: [
|
|
117
|
+
const selectProperties = args.options.selectProperties
|
|
118
|
+
? args.options.selectProperties.split(',')
|
|
119
|
+
: ['Title', 'OriginalPath'];
|
|
120
|
+
if (args.options.allResults) {
|
|
121
|
+
selectProperties.filter(p => p.toLowerCase() !== 'docid').push('DocId');
|
|
122
|
+
}
|
|
123
|
+
return selectProperties;
|
|
124
|
+
}
|
|
125
|
+
getSortList(args) {
|
|
126
|
+
const sortList = [];
|
|
127
|
+
if (args.options.allResults) {
|
|
128
|
+
sortList.push(formatting.encodeQueryParameter('[DocId]:ascending'));
|
|
129
|
+
}
|
|
130
|
+
if (args.options.sortList) {
|
|
131
|
+
const sortListArray = args.options.sortList.split(',');
|
|
132
|
+
sortListArray.forEach(sortItem => {
|
|
133
|
+
sortList.push(formatting.encodeQueryParameter(sortItem));
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return sortList.join(',');
|
|
110
137
|
}
|
|
111
138
|
async printResults(logger, args, results) {
|
|
112
139
|
if (args.options.rawOutput) {
|
|
@@ -116,9 +143,9 @@ class SpoSearchCommand extends SpoCommand {
|
|
|
116
143
|
await logger.log(this.getParsedOutput(args, results));
|
|
117
144
|
}
|
|
118
145
|
if (!args.options.output || cli.shouldTrimOutput(args.options.output)) {
|
|
119
|
-
await logger.log(
|
|
120
|
-
await logger.log(
|
|
121
|
-
await logger.log(
|
|
146
|
+
await logger.log('# Rows: ' + results[results.length - 1].PrimaryQueryResult.RelevantResults.TotalRows);
|
|
147
|
+
await logger.log('# Rows (Including duplicates): ' + results[results.length - 1].PrimaryQueryResult.RelevantResults.TotalRowsIncludingDuplicates);
|
|
148
|
+
await logger.log('Elapsed Time: ' + this.getElapsedTime(results));
|
|
122
149
|
}
|
|
123
150
|
}
|
|
124
151
|
getElapsedTime(results) {
|
|
@@ -245,6 +272,9 @@ _SpoSearchCommand_instances = new WeakSet(), _SpoSearchCommand_initTelemetry = f
|
|
|
245
272
|
if (args.options.startRow && !isNumber(args.options.startRow)) {
|
|
246
273
|
return `${args.options.startRow} is not a valid number`;
|
|
247
274
|
}
|
|
275
|
+
if (args.options.startRow && args.options.allResults) {
|
|
276
|
+
return 'You cannot specify startRow when allResults is set';
|
|
277
|
+
}
|
|
248
278
|
if (args.options.culture && !isNumber(args.options.culture)) {
|
|
249
279
|
return `${args.options.culture} is not a valid number`;
|
|
250
280
|
}
|
|
@@ -25,7 +25,7 @@ m365 spo search [options]
|
|
|
25
25
|
: The web against which we want to execute the query. If the parameter is not defined, the query is executed against the web that's used when logging in to the SPO environment.
|
|
26
26
|
|
|
27
27
|
`--allResults`
|
|
28
|
-
: Set, to get all results of the search query
|
|
28
|
+
: Set, to get all results of the search query in batches of 500.
|
|
29
29
|
|
|
30
30
|
`--rowLimit [rowLimit]`
|
|
31
31
|
: The number of rows to be returned. When the `allResults` option is used, the specified value will define the size of retrieved batches
|
|
@@ -55,7 +55,7 @@ m365 spo search [options]
|
|
|
55
55
|
: The ID of the ranking model to use for the query.
|
|
56
56
|
|
|
57
57
|
`--startRow [startRow]`
|
|
58
|
-
: The first row that is included in the search results that are returned. You use this parameter when you want to implement paging for search results.
|
|
58
|
+
: The first row that is included in the search results that are returned. You use this parameter when you want to implement manual paging for search results.
|
|
59
59
|
|
|
60
60
|
`--properties [properties]`
|
|
61
61
|
: Additional properties for the query.
|
|
@@ -90,6 +90,10 @@ m365 spo search [options]
|
|
|
90
90
|
|
|
91
91
|
<Global />
|
|
92
92
|
|
|
93
|
+
## Remarks
|
|
94
|
+
|
|
95
|
+
When using the `--allResults` option, you cannot use the `--startRow` option. Only use `--startRow` for manual paging purposes.
|
|
96
|
+
|
|
93
97
|
## Examples
|
|
94
98
|
|
|
95
99
|
Execute search query to retrieve all Document Sets (ContentTypeId = _0x0120D520_) for the English locale
|
package/package.json
CHANGED