-
Notifications
You must be signed in to change notification settings - Fork 4.5k
/
SearchOptions.cs
380 lines (349 loc) · 21.6 KB
/
SearchOptions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Azure.Core;
using Azure.Search.Documents.Models;
namespace Azure.Search.Documents
{
/// <summary>
/// Options for <see cref="SearchClient.SearchAsync(string, SearchOptions, CancellationToken)"/> that
/// allow specifying filtering, sorting, faceting, paging, and other search
/// query behaviors.
/// </summary>
/// <seealso href="https://docs.microsoft.com/rest/api/searchservice/search-documents#query-parameters">Query Parameters.</seealso>
[CodeGenModel("SearchRequest")]
public partial class SearchOptions
{
/// <summary> Initializes a new instance of <see cref="SearchOptions"/>. </summary>
/// <param name="includeTotalCount"> A value that specifies whether to fetch the total count of results. Default is false. Setting this value to true may have a performance impact. Note that the count returned is an approximation. </param>
/// <param name="facets"> The list of facet expressions to apply to the search query. Each facet expression contains a field name, optionally followed by a comma-separated list of name:value pairs. </param>
/// <param name="filter"> The OData $filter expression to apply to the search query. </param>
/// <param name="highlightFieldsRaw"> The comma-separated list of field names to use for hit highlights. Only searchable fields can be used for hit highlighting. </param>
/// <param name="highlightPostTag"> A string tag that is appended to hit highlights. Must be set with highlightPreTag. Default is </em>. </param>
/// <param name="highlightPreTag"> A string tag that is prepended to hit highlights. Must be set with highlightPostTag. Default is <em>. </param>
/// <param name="minimumCoverage"> A number between 0 and 100 indicating the percentage of the index that must be covered by a search query in order for the query to be reported as a success. This parameter can be useful for ensuring search availability even for services with only one replica. The default is 100. </param>
/// <param name="orderByRaw"> The comma-separated list of OData $orderby expressions by which to sort the results. Each expression can be either a field name or a call to either the geo.distance() or the search.score() functions. Each expression can be followed by asc to indicate ascending, or desc to indicate descending. The default is ascending order. Ties will be broken by the match scores of documents. If no $orderby is specified, the default sort order is descending by document match score. There can be at most 32 $orderby clauses. </param>
/// <param name="queryType"> A value that specifies the syntax of the search query. The default is 'simple'. Use 'full' if your query uses the Lucene query syntax. </param>
/// <param name="scoringStatistics"> A value that specifies whether we want to calculate scoring statistics (such as document frequency) globally for more consistent scoring, or locally, for lower latency. The default is 'local'. Use 'global' to aggregate scoring statistics globally before scoring. Using global scoring statistics can increase latency of search queries. </param>
/// <param name="sessionId"> A value to be used to create a sticky session, which can help getting more consistent results. As long as the same sessionId is used, a best-effort attempt will be made to target the same replica set. Be wary that reusing the same sessionID values repeatedly can interfere with the load balancing of the requests across replicas and adversely affect the performance of the search service. The value used as sessionId cannot start with a '_' character. </param>
/// <param name="scoringParameters"> The list of parameter values to be used in scoring functions (for example, referencePointParameter) using the format name-values. For example, if the scoring profile defines a function with a parameter called 'mylocation' the parameter string would be "mylocation--122.2,44.8" (without the quotes). </param>
/// <param name="scoringProfile"> The name of a scoring profile to evaluate match scores for matching documents in order to sort the results. </param>
/// <param name="searchText"> A full-text search query expression; Use "*" or omit this parameter to match all documents. </param>
/// <param name="searchFieldsRaw"> The comma-separated list of field names to which to scope the full-text search. When using fielded search (fieldName:searchExpression) in a full Lucene query, the field names of each fielded search expression take precedence over any field names listed in this parameter. </param>
/// <param name="searchMode"> A value that specifies whether any or all of the search terms must be matched in order to count the document as a match. </param>
/// <param name="selectRaw"> The comma-separated list of fields to retrieve. If unspecified, all fields marked as retrievable in the schema are included. </param>
/// <param name="skip"> The number of search results to skip. This value cannot be greater than 100,000. If you need to scan documents in sequence, but cannot use skip due to this limitation, consider using orderby on a totally-ordered key and filter with a range query instead. </param>
/// <param name="size"> The number of search results to retrieve. This can be used in conjunction with $skip to implement client-side paging of search results. If results are truncated due to server-side paging, the response will include a continuation token that can be used to issue another Search request for the next page of results. </param>
/// <param name="semanticConfigurationName"> The name of a semantic configuration that will be used when processing documents for queries of type semantic. </param>
/// <param name="semanticErrorMode"> Allows the user to choose whether a semantic call should fail completely (default / current behavior), or to return partial results. </param>
/// <param name="semanticMaxWaitInMilliseconds"> Allows the user to set an upper bound on the amount of time it takes for semantic enrichment to finish processing before the request fails. </param>
/// <param name="queryAnswerRaw"> A value that specifies whether answers should be returned as part of the search response. </param>
/// <param name="queryCaptionRaw"> A value that specifies whether captions should be returned as part of the search response. </param>
/// <param name="vectorQueries">
/// The query parameters for vector and hybrid search queries.
/// Please note <see cref="VectorQuery"/> is the base class. According to the scenario, a derived class of the base class might need to be assigned here, or this property needs to be casted to one of the possible derived classes.
/// The available derived classes include <see cref="VectorizedQuery"/>.
/// </param>
/// <param name="filterMode"> Determines whether or not filters are applied before or after the vector search is performed. Default is 'preFilter' for new indexes. </param>
internal SearchOptions(bool? includeTotalCount, IList<string> facets, string filter, string highlightFieldsRaw, string highlightPostTag, string highlightPreTag, double? minimumCoverage, string orderByRaw, SearchQueryType? queryType, ScoringStatistics? scoringStatistics, string sessionId, IList<string> scoringParameters, string scoringProfile, string searchText, string searchFieldsRaw, SearchMode? searchMode, string selectRaw, int? skip, int? size, string semanticConfigurationName, SemanticErrorMode? semanticErrorMode, int? semanticMaxWaitInMilliseconds, string queryAnswerRaw, string queryCaptionRaw, IList<VectorQuery> vectorQueries, VectorFilterMode? filterMode)
{
IncludeTotalCount = includeTotalCount;
Facets = facets;
Filter = filter;
HighlightFieldsRaw = highlightFieldsRaw;
HighlightPostTag = highlightPostTag;
HighlightPreTag = highlightPreTag;
MinimumCoverage = minimumCoverage;
OrderByRaw = orderByRaw;
QueryType = queryType;
ScoringStatistics = scoringStatistics;
SessionId = sessionId;
ScoringParameters = scoringParameters;
ScoringProfile = scoringProfile;
SearchText = searchText;
SearchFieldsRaw = searchFieldsRaw;
SearchMode = searchMode;
SelectRaw = selectRaw;
Skip = skip;
Size = size;
SemanticSearch = (semanticConfigurationName != null || semanticErrorMode != null || semanticMaxWaitInMilliseconds != null || queryAnswerRaw != null || queryCaptionRaw != null) ? new SemanticSearchOptions() : null;
if (SemanticSearch != null)
{
SemanticSearch.QueryAnswer = queryAnswerRaw != null ? new QueryAnswer() : null;
SemanticSearch.QueryCaption = queryCaptionRaw != null ? new QueryCaption() : null;
}
SemanticConfigurationName = semanticConfigurationName;
SemanticErrorMode = semanticErrorMode;
SemanticMaxWaitInMilliseconds = semanticMaxWaitInMilliseconds;
QueryAnswerRaw = queryAnswerRaw;
QueryCaptionRaw = queryCaptionRaw;
VectorSearch = (vectorQueries != null || filterMode != null) ? new VectorSearchOptions() : null;
VectorQueries = vectorQueries;
FilterMode = filterMode;
}
/// <summary>
/// Initializes a new instance of SearchOptions from a continuation
/// token to continue fetching results from a previous search.
/// </summary>
/// <param name="continuationToken">
/// Encapsulates the state required to fetch the next page of search
/// results from the index.
/// </param>
internal SearchOptions(string continuationToken) =>
Copy(SearchContinuationToken.Deserialize(continuationToken), this);
/// <summary>
/// A full-text search query expression; Use "*" or omit this
/// parameter to match all documents.
/// </summary>
[CodeGenMember("Search")]
internal string SearchText { get; set; }
/// <summary>
/// The OData $filter expression to apply to the search query. You can
/// use <see cref="SearchFilter.Create(FormattableString)"/> to help
/// construct the filter expression.
/// </summary>
/// <seealso href="https://docs.microsoft.com/azure/search/search-filters">Filters in Azure Cognitive Search</seealso>
[CodeGenMember("Filter")]
public string Filter { get; set; }
/// <summary>
/// The list of field names to use for hit highlights. Only searchable
/// fields can be used for hit highlighting.
/// </summary>
public IList<string> HighlightFields { get; internal set; } = new List<string>();
/// <summary>
/// Join HighlightFields so it can be sent as a comma separated string.
/// </summary>
[CodeGenMember("HighlightFields")]
internal string HighlightFieldsRaw
{
get => HighlightFields.CommaJoin();
set => HighlightFields = SearchExtensions.CommaSplit(value);
}
/// <summary>
/// The list of field names to which to scope the full-text search.
/// When using fielded search (fieldName:searchExpression) in a full
/// Lucene query, the field names of each fielded search expression
/// take precedence over any field names listed in this parameter.
/// </summary>
public IList<string> SearchFields { get; internal set; } = new List<string>();
/// <summary>
/// Join SearchFields so it can be sent as a comma separated string.
/// </summary>
[CodeGenMember("SearchFields")]
internal string SearchFieldsRaw
{
get => SearchFields.CommaJoin();
set => SearchFields = SearchExtensions.CommaSplit(value);
}
/// <summary>
/// The list of fields to retrieve. If unspecified, all fields marked
/// as retrievable in the schema are included.
/// </summary>
public IList<string> Select { get; internal set; } = new List<string>();
/// <summary>
/// Join Select so it can be sent as a comma separated string.
/// </summary>
[CodeGenMember("Select")]
internal string SelectRaw
{
get => Select.CommaJoin();
set => Select = SearchExtensions.CommaSplit(value);
}
/// <summary>
/// The number of search results to retrieve. This can be used in
/// conjunction with <see cref="Skip"/> to implement client-side
/// paging of search results. If results are truncated due to
/// server-side paging, the response will include a continuation token
/// that can be used to issue another Search request for the next page
/// of results.
/// </summary>
[CodeGenMember("Top")]
public int? Size { get; set; }
/// <summary>
/// The list of OData $orderby expressions by which to sort the
/// results. Each expression can be either a field name or a call to
/// either the geo.distance() or the search.score() functions. Each
/// expression can be followed by asc to indicate ascending, or desc to
/// indicate descending. The default is ascending order. Ties will be
/// broken by the match scores of documents. If no $orderby is
/// specified, the default sort order is descending by document match
/// score. There can be at most 32 $orderby clauses.
/// </summary>
public IList<string> OrderBy { get; internal set; } = new List<string>();
/// <summary>
/// Join OrderBy so it can be sent as a comma separated string.
/// </summary>
[CodeGenMember("OrderBy")]
internal string OrderByRaw
{
get => OrderBy.CommaJoin();
set => OrderBy = SearchExtensions.CommaSplit(value);
}
/// <summary>
/// A value that specifies whether to fetch the total count of results
/// as the <see cref="Models.SearchResults{T}.TotalCount"/> property.
/// The default value is false. Setting this value to true may have a
/// performance impact. Note that the count returned is an
/// approximation.
/// </summary>
[CodeGenMember("IncludeTotalResultCount")]
public bool? IncludeTotalCount { get; set; }
/// <summary>
/// The list of facet expressions to apply to the search query. Each
/// facet expression contains a field name, optionally followed by a
/// comma-separated list of name:value pairs.
/// </summary>
/// <seealso href="https://docs.microsoft.com/azure/search/search-filters-facets">How to build a facet filter in Azure Cognitive Search.</seealso>
[CodeGenMember("Facets")]
public IList<string> Facets { get; internal set; } = new List<string>();
/// <summary>
/// The list of parameter values to be used in scoring functions (for
/// example, referencePointParameter) using the format name-values. For
/// example, if the scoring profile defines a function with a parameter
/// called 'mylocation' the parameter string would be
/// "mylocation--122.2,44.8" (without the quotes).
/// </summary>
[CodeGenMember("ScoringParameters")]
public IList<string> ScoringParameters { get; internal set; } = new List<string>();
/// <summary> Options for performing Semantic Search. </summary>
public SemanticSearchOptions SemanticSearch { get; set; }
/// <summary> Options for performing Vector Search. </summary>
public VectorSearchOptions VectorSearch { get; set; }
/// <summary> The name of a semantic configuration that will be used when processing documents for queries of type semantic. </summary>
[CodeGenMember("SemanticConfiguration")]
private string SemanticConfigurationName
{
get { return SemanticSearch?.SemanticConfigurationName; }
set
{
if (SemanticSearch != null)
{
SemanticSearch.SemanticConfigurationName = value;
}
}
}
/// <summary> Constructed from <see cref="QueryAnswer.AnswerType"/>, <see cref="QueryAnswer.Count"/> and <see cref="QueryAnswer.Threshold"/>. For example: "extractive|count-1,threshold-0.7"</summary>
[CodeGenMember("Answers")]
private string QueryAnswerRaw
{
get { return SemanticSearch?.QueryAnswer?.QueryAnswerRaw; }
set
{
if (SemanticSearch?.QueryAnswer != null)
{
SemanticSearch.QueryAnswer.QueryAnswerRaw = value;
}
}
}
/// <summary> Constructed from <see cref="QueryCaption.CaptionType"/> and <see cref="QueryCaption.HighlightEnabled"/>.</summary>
[CodeGenMember("Captions")]
private string QueryCaptionRaw
{
get { return SemanticSearch?.QueryCaption?.QueryCaptionRaw; }
set
{
if (SemanticSearch?.QueryCaption != null)
{
SemanticSearch.QueryCaption.QueryCaptionRaw = value;
}
}
}
/// <summary> Allows the user to choose whether a semantic call should fail completely (default / current behavior), or to return partial results. </summary>
[CodeGenMember("SemanticErrorHandling")]
private SemanticErrorMode? SemanticErrorMode
{
get { return SemanticSearch?.ErrorMode; }
set
{
if (SemanticSearch != null)
{
SemanticSearch.ErrorMode = value;
}
}
}
/// <summary> Allows the user to set an upper bound on the amount of time it takes for semantic enrichment to finish processing before the request fails. </summary>
private int? SemanticMaxWaitInMilliseconds
{
get
{
return (int?)SemanticSearch?.MaxWait?.TotalMilliseconds;
}
set
{
if (SemanticSearch != null)
{
SemanticSearch.MaxWait = value.HasValue ? TimeSpan.FromMilliseconds(value.Value) : null;
}
}
}
/// <summary> The query parameters for multi-vector search queries. </summary>
private IList<VectorQuery> VectorQueries
{
get { return VectorSearch?.Queries != null ? VectorSearch.Queries : new ChangeTrackingList<VectorQuery>(); }
set
{
if (VectorSearch != null)
{
VectorSearch.Queries = value;
}
}
}
/// <summary> Determines whether or not filters are applied before or after the vector search is performed. Default is <see cref="VectorFilterMode.PreFilter" /> for new indexes. </summary>
[CodeGenMember("VectorFilterMode")]
private VectorFilterMode? FilterMode
{
get { return VectorSearch?.FilterMode; }
set
{
if (VectorSearch != null)
{
VectorSearch.FilterMode = value;
}
}
}
/// <summary>
/// Shallow copy one SearchOptions instance to another.
/// </summary>
/// <param name="source">The source options.</param>
/// <param name="destination">The destination options.</param>
private static void Copy(SearchOptions source, SearchOptions destination)
{
System.Diagnostics.Debug.Assert(source != null);
System.Diagnostics.Debug.Assert(destination != null);
destination.Facets = source.Facets;
destination.Filter = source.Filter;
destination.HighlightFields = source.HighlightFields;
destination.HighlightPostTag = source.HighlightPostTag;
destination.HighlightPreTag = source.HighlightPreTag;
destination.IncludeTotalCount = source.IncludeTotalCount;
destination.MinimumCoverage = source.MinimumCoverage;
destination.OrderBy = source.OrderBy;
destination.QueryType = source.QueryType;
destination.ScoringParameters = source.ScoringParameters;
destination.ScoringProfile = source.ScoringProfile;
destination.ScoringStatistics = source.ScoringStatistics;
destination.SearchFields = source.SearchFields;
destination.SearchMode = source.SearchMode;
destination.SearchText = source.SearchText;
destination.Select = source.Select;
destination.SessionId = source.SessionId;
destination.Size = source.Size;
destination.Skip = source.Skip;
destination.SemanticSearch = source.SemanticSearch;
destination.VectorSearch = source.VectorSearch;
}
/// <summary>
/// Creates a shallow copy of the SearchOptions.
/// </summary>
/// <returns>The cloned SearchOptions.</returns>
internal SearchOptions Clone()
{
SearchOptions clone = new SearchOptions();
Copy(this, clone);
return clone;
}
}
}