[search] Updates for preview 1 (#7641)

Address feedback for preview 1
This commit is contained in:
Jeff Fisher 2020-03-06 19:11:29 -08:00 коммит произвёл GitHub
Родитель 8d81639bce
Коммит 6bbed0db4a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
28 изменённых файлов: 759 добавлений и 375 удалений

2
.github/CODEOWNERS поставляемый
Просмотреть файл

@ -34,6 +34,8 @@
/sdk/test-utils/ @HarshaNalluru @sadasant
/sdk/textanalytics/ @xirzec @willmtemple
/sdk/search/ @xirzec
# API review files
/sdk/**/review/*api.md @bterlson

Просмотреть файл

@ -123,7 +123,11 @@
"**/test-dist/*": true,
"**/node_modules": true,
"**/bower_components": true,
"**/*.code-search": true
"**/*.code-search": true,
"**/types/*": true,
"**/coverage/*": true,
"**/*.d.ts": true,
"**/test-browser/*": true
},
},

Просмотреть файл

@ -0,0 +1,6 @@
# Release History
## 11.0.0-preview.1 (Unreleased)
- Initial implementation of the data-plane Cognitive Search Client. The version number starts at 11 to align with client libraries in other languages.
- This first preview has support for document operations on an index, such as querying and document management.

Просмотреть файл

@ -1,6 +1,6 @@
# Azure Cognitive Search client library for JavaScript
[Azure Cognitive Search](https://docs.microsoft.com/en-us/azure/search/) is a search-as-a-service cloud solution that gives developers APIs and tools for adding a rich search experience over private, heterogeneous content in web, mobile, and enterprise applications.
[Azure Cognitive Search](https://docs.microsoft.com/azure/search/) is a search-as-a-service cloud solution that gives developers APIs and tools for adding a rich search experience over private, heterogeneous content in web, mobile, and enterprise applications.
Azure Cognitive Search is well suited for the following application scenarios:
@ -20,7 +20,7 @@ Use the client library to:
[Source code](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/search/search/) |
[Package (NPM)](https://www.npmjs.com/package/@azure/search) |
[API reference documentation](https://aka.ms/azsdk-js-search-ref-docs) |
[Product documentation](https://docs.microsoft.com/en-us/azure/search/) |
[Product documentation](https://docs.microsoft.com/azure/search/) |
[Samples](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search/samples)
## Getting started
@ -32,7 +32,7 @@ Use the client library to:
### Prerequisites
- An [Azure subscription][azure_sub].
- An existing [Cognitive Search][search_resource] resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli].
- An existing [Azure Cognitive Search][search_resource] resource. If you need to create the resource, you can use the [Azure Portal][azure_portal] or [Azure CLI][azure_cli].
If you use the Azure CLI, replace `<your-resource-group-name>` and `<your-resource-name>` with your own unique names:
@ -40,7 +40,7 @@ If you use the Azure CLI, replace `<your-resource-group-name>` and `<your-resour
az search service create --resource-group <your-resource-group-name> --name <your-resource-name> --sku S
```
The above creates a resource with the "Standard" pricing tier. See [choosing a pricing tier](https://docs.microsoft.com/en-us/azure/search/search-sku-tier) for more information.
The above creates a resource with the "Standard" pricing tier. See [choosing a pricing tier](https://docs.microsoft.com/azure/search/search-sku-tier) for more information.
### 1. Install the `@azure/search` package
@ -50,11 +50,11 @@ npm install @azure/search
### 2. Create and authenticate a `SearchIndexClient`
Cognitive Search uses keys for authentication.
Azure Cognitive Search uses keys for authentication.
#### Using an Admin Key
Use the [Azure CLI][azure_cli] snippet below to get the Admin Key from the Cognitive Search resource.
Use the [Azure CLI][azure_cli] snippet below to get the Admin Key from the Azure Cognitive Search resource.
```PowerShell
az search admin-key show --resource-group <your-resource-group-name> --service-name <your-resource-name>
@ -78,13 +78,27 @@ const client = new SearchIndexClient(
### SearchIndexClient
`SearchIndexClient` is one of the primary interface for developers using the Cognitive Search client library. It provides asynchronous methods for working with documents in an index.
`SearchIndexClient` is one of the primary interface for developers using the Azure Cognitive Search client library. It provides asynchronous methods for working with documents in an index. These methods allow you to query, upload, update, and delete documents. It also provides methods for building completion and suggestion experiences based on partial queries.
### Pagination
Typically you will only wish to [show a subset of search results](https://docs.microsoft.com/azure/search/search-pagination-page-layout#total-hits-and-page-counts) to a user at one time. To support this, you can use the `top`, `skip` and `includeTotalResultCount` parameters to provide a paged experience on top of search results.
### Document field encoding
[Supported data types](https://docs.microsoft.com/rest/api/searchservice/Supported-data-types) in an index are mapped to JSON types in API requests/responses. The JS client library keeps these mostly the same, with some exceptions:
- `Edm.DateTimeOffset` is converted to a JS `Date`.
- `Edm.GeographyPoint` is converted to a `GeographyPoint` type exported by the client library.
- Special values of the `number` type (NaN, Infinity, -Infinity) are serialized as strings in the REST API, but are converted back to `number` by the client library.
**Note**: Data types are converted based on value, not the field type in the index schema. This means that if you have an ISO8601 Date string (e.g. "2020-03-06T18:48:27.896Z") as the value of a field, it will be converted to a Date regardless of how you stored it in your schema.
## Examples
### Query documents in an index
To list all results of a particular query, you can use `listSearchResults` with a search string that uses [simple query syntax](https://docs.microsoft.com/en-us/azure/search/query-simple-syntax):
To list all results of a particular query, you can use `search` with a search string that uses [simple query syntax](https://docs.microsoft.com/azure/search/query-simple-syntax):
```js
const { SearchIndexClient, SearchApiKeyCredential } = require("@azure/search");
@ -95,13 +109,13 @@ const client = new SearchIndexClient(
new SearchApiKeyCredential("<Admin Key>");
);
const iterator = client.listSearchResults({ searchText: "wifi -luxury"});
for await (const result of iterator) {
const searchResults = await client.search({ searchText: "wifi -luxury"});
for await (const result of searchResults.results) {
console.log(result);
}
```
For a more advanced search that uses [Lucene syntax](https://docs.microsoft.com/en-us/azure/search/query-lucene-syntax), specify `queryType` to be `all`:
For a more advanced search that uses [Lucene syntax](https://docs.microsoft.com/azure/search/query-lucene-syntax), specify `queryType` to be `all`:
```js
const { SearchIndexClient, SearchApiKeyCredential } = require("@azure/search");
@ -112,12 +126,12 @@ const client = new SearchIndexClient(
new SearchApiKeyCredential("<Admin Key>");
);
const iterator = client.listSearchResults({
const searchResults = await client.search({
searchText: 'category:budget AND "recently renovated"^3',
queryType: "full",
searchMode: "all"
});
for await (const result of iterator) {
for await (const result of searchResults.results) {
console.log(result);
}
```
@ -145,14 +159,14 @@ const client = new SearchIndexClient<Hotel>(
new SearchApiKeyCredential("<Admin Key>");
);
const iterator = client.listSearchResults({
const searchResults = await client.search({
searchText: "wifi -luxury",
// Only fields in Hotel can be added to this array.
// TS will complain if one is misspelled.
select: ["HotelId", "HotelName", "Rating"]
});
for await (const result of iterator) {
for await (const result of searchResults.results) {
// result has HotelId, HotelName, and Rating.
// Trying to access result.Description would emit a TS error.
console.log(result.HotelName);
@ -161,7 +175,7 @@ for await (const result of iterator) {
### Querying with OData filters
Using the `filter` query parameter allows you to query an index using the syntax of an [OData \$filter expression](https://docs.microsoft.com/en-us/azure/search/search-query-odata-filter).
Using the `filter` query parameter allows you to query an index using the syntax of an [OData \$filter expression](https://docs.microsoft.com/azure/search/search-query-odata-filter).
```js
const { SearchIndexClient, SearchApiKeyCredential, odata } = require("@azure/search");
@ -174,13 +188,13 @@ const client = new SearchIndexClient(
const baseRateMax = 200;
const ratingMin = 4;
const iterator = client.listSearchResults({
const searchResults = await client.search({
searchText: "WiFi",
filter: odata`Rooms/any(room: room/BaseRate lt ${baseRateMax}) and Rating ge ${ratingMin}`,
orderBy: "Rating desc",
orderBy: ["Rating desc"],
select: ["HotelId", "HotelName", "Rating"]
});
for await (const result of iterator) {
for await (const result of searchResults.results) {
// Each result will have "HotelId", "HotelName", and "Rating"
// in addition to the standard search result property "score"
console.log(result);
@ -189,7 +203,7 @@ for await (const result of iterator) {
### Querying with facets
[Facets](https://docs.microsoft.com/en-us/azure/search/search-filters-facets) are used to help a user of your application refine a search along pre-configured dimensions. [Facet syntax](https://docs.microsoft.com/en-us/rest/api/searchservice/search-documents#facetstring-zero-or-more) provides the options to sort and bucket facet values.
[Facets](https://docs.microsoft.com/azure/search/search-filters-facets) are used to help a user of your application refine a search along pre-configured dimensions. [Facet syntax](https://docs.microsoft.com/rest/api/searchservice/search-documents#facetstring-zero-or-more) provides the options to sort and bucket facet values.
```js
const { SearchIndexClient, SearchApiKeyCredential } = require("@azure/search");
@ -200,15 +214,12 @@ const client = new SearchIndexClient(
new SearchApiKeyCredential("<Admin Key>");
);
const iterator = await client
.listSearchResults({
const searchResults = await client
.search({
searchText: "WiFi",
facets: ["Category,count:3,sort:count", "Rooms/BaseRate,interval:100"]
})
.byPage();
const page = (await iterator.next()).value;
console.log(page.facets);
});
console.log(searchResults.facets);
// Output will look like:
// {
// Rating: [
@ -250,7 +261,7 @@ console.log(result);
### Retrieve suggestions from an index
If you [created a suggester](https://docs.microsoft.com/en-us/azure/search/index-add-suggesters) on your index, you can use it to return result suggestions for a user query.
If you [created a suggester](https://docs.microsoft.com/azure/search/index-add-suggesters) on your index, you can use it to return result suggestions for a user query.
This example shows returning the top three suggestions for the input "wifi" from the suggester "sg":
@ -279,7 +290,7 @@ for (const result of suggestResult.results) {
### Autocomplete a partial query using an index
To implement type-ahead behavior in your application, you can query the index with partial user input and return a list of suggested completions. You must have [created a suggester](https://docs.microsoft.com/en-us/azure/search/index-add-suggesters) on your index first.
To implement type-ahead behavior in your application, you can query the index with partial user input and return a list of suggested completions. You must have [created a suggester](https://docs.microsoft.com/azure/search/index-add-suggesters) on your index first.
The below example tries to complete the string "de" using the suggester named "sg" on the index:
@ -313,7 +324,7 @@ const client = new SearchIndexClient(
new SearchApiKeyCredential("<Admin Key>");
);
const count = await client.count();
const count = await client.countDocuments();
console.log(`${count} documents in index ${client.indexName}`);
```
@ -364,7 +375,7 @@ for (const result of uploadResult.results) {
### Update existing documents in an index
You can update multiple documents in an index at once, or create them if they do not exist. For more details about how merging works, see: https://docs.microsoft.com/en-us/rest/api/searchservice/AddUpdate-or-Delete-Documents
You can update multiple documents in an index at once, or create them if they do not exist. For more details about how merging works, see: https://docs.microsoft.com/rest/api/searchservice/AddUpdate-or-Delete-Documents
```js
@ -376,7 +387,7 @@ const client = new SearchIndexClient(
new SearchApiKeyCredential("<Admin Key>");
);
const updateResult = await client.updateDocuments([
const updateResult = await client.mergeDocuments([
// JSON objects matching the shape of the client's index
{ ... },
{ ... },
@ -398,12 +409,14 @@ for (const result of updateResult.results) {
You can set the following environment variable to get the debug logs when using this library.
- Getting debug logs from the Azure Search client library
- Getting debug logs from the Azure Cognitive Search client library
```bash
export AZURE_LOG_LEVEL=verbose*
```
For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/logger).
## Next steps
Please take a look at the
@ -434,6 +447,6 @@ If you'd like to contribute to this library, please read the [contributing guide
[azure_cli]: https://docs.microsoft.com/cli/azure
[azure_sub]: https://azure.microsoft.com/free/
[search_resource]: https://docs.microsoft.com/en-us/azure/search/search-create-service-portal
[search_resource]: https://docs.microsoft.com/azure/search/search-create-service-portal
[azure_portal]: https://portal.azure.com
[cognitive_auth]: https://docs.microsoft.com/en-us/azure/cognitive-services/authentication
[cognitive_auth]: https://docs.microsoft.com/azure/cognitive-services/authentication

Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "@azure/search",
"version": "1.0.0-preview.1",
"version": "11.0.0-preview.1",
"description": "Azure client library to use Cognitive Search for node.js and browser.",
"sdk-type": "client",
"main": "dist/index.js",
@ -10,19 +10,21 @@
"audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit",
"build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1",
"build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1",
"build:samples": "cd samples && tsc -p .",
"build:samples": "node ../../../common/scripts/prep-samples.js && cd samples && tsc -p .",
"build:test": "tsc -p . && rollup -c rollup.test.config.js 2>&1",
"build": "tsc -p . && rollup -c 2>&1 && api-extractor run --local",
"check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"clean": "rimraf dist dist-esm test-dist temp types *.tgz *.log",
"execute:samples": "echo skipped",
"execute:js-samples": "node ../../../common/scripts/run-samples.js samples/javascript/",
"execute:ts-samples": "node ../../../common/scripts/run-samples.js samples/typescript/dist/samples/typescript/src/",
"execute:samples": "npm run build:samples && npm run execute:js-samples && npm run execute:ts-samples",
"extract-api": "tsc -p . && api-extractor run --local",
"format": "prettier --write --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"integration-test:browser": "echo skipped",
"integration-test:node": "echo skipped",
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
"lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]",
"lint": "eslint package.json api-extractor.json src test --ext .ts -f html -o template-lintReport.html || exit 0",
"lint": "eslint package.json api-extractor.json src test --ext .ts -f html -o search-lintReport.html || exit 0",
"pack": "npm pack 2>&1",
"prebuild": "npm run clean",
"test:browser": "npm run build:test && npm run unit-test:browser && npm run integration-test:browser",

Просмотреть файл

@ -12,8 +12,8 @@ import { WebResource } from '@azure/core-http';
// @public
export interface AutocompleteItem {
readonly queryPlusText?: string;
readonly text?: string;
readonly queryPlusText: string;
readonly text: string;
}
// @public
@ -39,14 +39,14 @@ export interface AutocompleteRequest<Fields> {
// @public
export interface AutocompleteResult {
readonly coverage?: number;
readonly results?: AutocompleteItem[];
readonly results: AutocompleteItem[];
}
// @public
export type CountOptions = OperationOptions;
export type CountDocumentsOptions = OperationOptions;
// @public
export type DeleteDocumentsOptions = ModifyIndexOptions;
export type DeleteDocumentsOptions = IndexDocuments;
// @public
export interface FacetResult {
@ -68,36 +68,40 @@ export interface GetDocumentOptions<Fields> extends OperationOptions {
}
// @public
export interface IndexAction {
[property: string]: any;
actionType?: IndexActionType;
}
export type IndexAction<T> = {
actionType: IndexActionType;
} & Partial<T>;
// @public
export type IndexActionType = 'upload' | 'merge' | 'mergeOrUpload' | 'delete';
// @public
export interface IndexDocuments extends OperationOptions {
throwOnAnyFailure?: boolean;
}
// @public
export interface IndexDocumentsResult {
readonly results?: IndexingResult[];
readonly results: IndexingResult[];
}
// @public
export interface IndexingResult {
readonly errorMessage?: string;
readonly key?: string;
readonly statusCode?: number;
readonly succeeded?: boolean;
readonly key: string;
readonly statusCode: number;
readonly succeeded: boolean;
}
// @public
export interface ListSearchResultsPageSettings {
nextLink?: string;
nextPageParameters?: SearchRequest<string>;
nextPageParameters?: RawSearchRequest;
}
// @public
export interface ModifyIndexOptions extends OperationOptions {
throwOnAnyFailure?: boolean;
export interface MergeDocumentsOptions extends IndexDocuments {
uploadIfNotExists?: boolean;
}
// @public
@ -106,6 +110,27 @@ export function odata(strings: TemplateStringsArray, ...values: unknown[]): stri
// @public
export type QueryType = 'simple' | 'full';
// @public
export interface RawSearchRequest {
facets?: string[];
filter?: string;
highlightFields?: string;
highlightPostTag?: string;
highlightPreTag?: string;
includeTotalResultCount?: boolean;
minimumCoverage?: number;
orderBy?: string;
queryType?: QueryType;
scoringParameters?: string[];
scoringProfile?: string;
searchFields?: string;
searchMode?: SearchMode;
searchText?: string;
select?: string;
skip?: number;
top?: number;
}
// @public
export class SearchApiKeyCredential implements ServiceClientCredentials {
constructor(apiKey: string);
@ -113,16 +138,25 @@ export class SearchApiKeyCredential implements ServiceClientCredentials {
updateKey(apiKey: string): void;
}
// @public (undocumented)
export interface SearchDocumentsPageResult<T> extends SearchDocumentsResultBase {
readonly nextLink?: string;
readonly nextPageParameters?: RawSearchRequest;
readonly results: SearchResult<T>[];
}
// @public (undocumented)
export interface SearchDocumentsResult<T> extends SearchDocumentsResultBase {
readonly results: SearchIterator<T>;
}
// @public
export interface SearchDocumentsResult<T> {
export interface SearchDocumentsResultBase {
readonly count?: number;
readonly coverage?: number;
readonly facets?: {
[propertyName: string]: FacetResult[];
};
readonly nextLink?: string;
readonly nextPageParameters?: SearchRequest<string>;
readonly results?: SearchResult<T>[];
}
// @public
@ -130,15 +164,15 @@ export class SearchIndexClient<T> {
constructor(endpoint: string, indexName: string, credential: SearchApiKeyCredential, options?: SearchIndexClientOptions);
readonly apiVersion: string;
autocomplete<Fields extends keyof T>(options: AutocompleteOptions<Fields>): Promise<AutocompleteResult>;
count(options?: CountOptions): Promise<number>;
deleteDocuments(keyName: string, keyValues: string[], options?: DeleteDocumentsOptions): Promise<IndexDocumentsResult>;
countDocuments(options?: CountDocumentsOptions): Promise<number>;
deleteDocuments(keyName: keyof T, keyValues: string[], options?: DeleteDocumentsOptions): Promise<IndexDocumentsResult>;
readonly endpoint: string;
getDocument<Fields extends keyof T>(key: string, options?: GetDocumentOptions<Fields>): Promise<T>;
indexDocuments(batch: IndexAction<T>[], options?: IndexDocuments): Promise<IndexDocumentsResult>;
readonly indexName: string;
listSearchResults<Fields extends keyof T>(options?: SearchOptions<Fields>): SearchIterator<Pick<T, Fields>>;
modifyIndex(batch: IndexAction[], options?: ModifyIndexOptions): Promise<IndexDocumentsResult>;
suggest<Fields extends keyof T>(options: SuggestOptions<Fields>): Promise<SuggestDocumentsResult<Pick<T, Fields>>>;
updateDocuments(documents: T[], options?: UpdateDocumentsOptions): Promise<IndexDocumentsResult>;
mergeDocuments(documents: T[], options?: MergeDocumentsOptions): Promise<IndexDocumentsResult>;
search<Fields extends keyof T>(options?: SearchOptions<Fields>): Promise<SearchDocumentsResult<Pick<T, Fields>>>;
suggest<Fields extends keyof T = never>(options: SuggestOptions<Fields>): Promise<SuggestDocumentsResult<Pick<T, Fields>>>;
uploadDocuments(documents: T[], options?: UploadDocumentsOptions): Promise<IndexDocumentsResult>;
}
@ -146,7 +180,7 @@ export class SearchIndexClient<T> {
export type SearchIndexClientOptions = PipelineOptions;
// @public
export type SearchIterator<Fields> = PagedAsyncIterableIterator<SearchResult<Fields>, SearchDocumentsResult<Fields>, ListSearchResultsPageSettings>;
export type SearchIterator<Fields> = PagedAsyncIterableIterator<SearchResult<Fields>, SearchDocumentsPageResult<Fields>, ListSearchResultsPageSettings>;
// @public
export type SearchMode = 'any' | 'all';
@ -163,7 +197,7 @@ export interface SearchRequest<Fields> {
highlightPreTag?: string;
includeTotalResultCount?: boolean;
minimumCoverage?: number;
orderBy?: string;
orderBy?: string[];
queryType?: QueryType;
scoringParameters?: string[];
scoringProfile?: string;
@ -177,7 +211,7 @@ export interface SearchRequest<Fields> {
// @public
export type SearchResult<T> = {
readonly score?: number;
readonly score: number;
readonly highlights?: {
[propertyName: string]: string[];
};
@ -186,7 +220,7 @@ export type SearchResult<T> = {
// @public
export interface SuggestDocumentsResult<T> {
readonly coverage?: number;
readonly results?: SuggestResult<T>[];
readonly results: SuggestResult<T>[];
}
// @public
@ -198,7 +232,7 @@ export interface SuggestRequest<Fields> {
highlightPostTag?: string;
highlightPreTag?: string;
minimumCoverage?: number;
orderBy?: string;
orderBy?: string[];
searchFields?: Fields[];
searchText: string;
select?: Fields[];
@ -209,16 +243,11 @@ export interface SuggestRequest<Fields> {
// @public
export type SuggestResult<T> = {
readonly text?: string;
readonly text: string;
} & T;
// @public
export interface UpdateDocumentsOptions extends ModifyIndexOptions {
uploadIfNotExists?: boolean;
}
// @public
export interface UploadDocumentsOptions extends ModifyIndexOptions {
export interface UploadDocumentsOptions extends IndexDocuments {
mergeIfExists?: boolean;
}

Просмотреть файл

@ -0,0 +1,49 @@
# Azure Cognitive Search client library samples for JavaScript
These sample programs show how to use the JavaScript client libraries for Azure Cognitive Search in some common scenarios.
| **File Name** | **Description** |
| ---------------------------- | ------------------------ |
| [readonlyQuery.js][readonly] | queries a public dataset |
## Prerequisites
The samples are compatible with Node.js >= 8.0.0.
You need [an Azure subscription][freesub] and [an Azure Cognitive Search service][search_resource] to run these sample programs. Samples retrieve credentials to access the Azure Cognitive Search endpoint from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.
Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package].
## Setup
To run the samples using the published version of the package:
1. Install the dependencies using `npm`:
```bash
npm install
```
2. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.
3. Run whichever samples you like (note that some samples may require additional setup, see the table above):
```bash
node readonlyQuery.js
```
Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform):
```bash
npx cross-env SEARCH_API_ENDPOINT="<endpoint>" SEARCH_API_KEY="<api key>" node readonlyQuery.js
```
## Next Steps
Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.
[readonly]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search/samples/javascript/readonlyQuery.js
[apiref]: https://aka.ms/azsdk-js-search-ref-docs
[search_resource]: https://docs.microsoft.com/azure/search/search-create-service-portal
[freesub]: https://azure.microsoft.com/free/
[package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search/README.md

Просмотреть файл

@ -0,0 +1,31 @@
{
"name": "azure-search-samples-js",
"private": true,
"version": "0.1.0",
"description": "Azure Cognitive Search client library samples for JavaScript",
"engine": {
"node": ">=8.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Azure/azure-sdk-for-js.git"
},
"keywords": [
"Azure",
"Search",
"Node.js",
"JavaScript"
],
"author": "Microsoft Corporation",
"license": "MIT",
"bugs": {
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
},
"homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search",
"sideEffects": false,
"dependencies": {
"@azure/search": "latest",
"@azure/identity": "latest",
"dotenv": "^8.2.0"
}
}

Просмотреть файл

@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* Performs a query over a public dataset
*/
const { SearchIndexClient, SearchApiKeyCredential, odata } = require("@azure/search");
// Load the .env file if it exists
require("dotenv").config();
async function main() {
console.log(`Running readonly query sample`);
// Variables provided by https://docs.microsoft.com/en-us/samples/azure-samples/azure-search-sample-data/azure-search-sample-data/
const endpoint = "https://azs-playground.search.windows.net";
const apiKey = "EA4510A6219E14888741FCFC19BFBB82";
const indexName = "hotels";
const credential = new SearchApiKeyCredential(apiKey);
const client = new SearchIndexClient(endpoint, indexName, credential);
const count = await client.countDocuments();
console.log(`${count} documents in index ${client.indexName}`);
const state = "FL";
const country = "USA";
const searchResults = await client.search({
searchText: "WiFi",
filter: odata`Address/StateProvince eq ${state} and Address/Country eq ${country}`,
orderBy: ["Rating desc"],
select: ["HotelId", "HotelName", "Rating"]
});
for await (const result of searchResults.results) {
console.log(`${result.HotelName}: ${result.Rating} stars`);
}
}
main().catch((err) => {
console.error("The sample encountered an error:", err);
});

Просмотреть файл

@ -0,0 +1,6 @@
# Used in most samples. Retrieve these values from a Cognitive Services instance
# in the Azure Portal.
SEARCH_API_KEY=<search api key>
SEARCH_API_ENDPOINT=https://<resource name>.search.windows.net
INDEX_NAME=hotels-sample-index

Просмотреть файл

@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "typescript/dist",
"lib": ["DOM", "ES6"]
},
"include": ["typescript/src/**.ts"],
"exclude": ["typescript/*.json", "**/node_modules/", "../node_modules", "../typings"]
}

Просмотреть файл

@ -0,0 +1,62 @@
# Azure Cognitive Search client library samples for TypeScript
These sample programs show how to use the TypeScript client libraries for Azure Cognitive Search in some common scenarios.
| **File Name** | **Description** |
| ---------------------------- | ------------------------ |
| [readonlyQuery.ts][readonly] | queries a public dataset |
## Prerequisites
The samples are compatible with Node.js >= 8.0.0.
Before running the samples in Node, they must be compiled to JavaScript using the TypeScript compiler. For more information on TypeScript, see the [TypeScript documentation][typescript]. Install the TypeScript compiler using
```bash
npm install -g typescript
```
You need [an Azure subscription][freesub] and [an Azure Cognitive Search service][search_resource] to run these sample programs. Samples retrieve credentials to access the Azure Cognitive Search endpoint from environment variables. Alternatively, edit the source code to include the appropriate credentials. See each individual sample for details on which environment variables/credentials it requires to function.
Adapting the samples to run in the browser may require some additional consideration. For details, please see the [package README][package].
## Setup
To run the samples using the published version of the package:
1. Install the dependencies using `npm`:
```bash
npm install
```
2. Compile the samples
```bash
npm run build
```
3. Edit the file `sample.env`, adding the correct credentials to access the Azure service and run the samples. Then rename the file from `sample.env` to just `.env`. The sample programs will read this file automatically.
4. Run whichever samples you like (note that some samples may require additional setup, see the table above):
```bash
node dist/readonlyQuery.js
```
Alternatively, run a single sample with the correct environment variables set (step 3 is not required if you do this), for example (cross-platform):
```bash
npx cross-env SEARCH_API_ENDPOINT="<endpoint>" SEARCH_API_KEY="<api key>" node dist/readonlyQuery.js
```
## Next Steps
Take a look at our [API Documentation][apiref] for more information about the APIs that are available in the clients.
[readonly]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search/samples/typescript/src/readonlyQuery.ts
[apiref]: https://aka.ms/azsdk-js-search-ref-docs
[search_resource]: https://docs.microsoft.com/azure/search/search-create-service-portal
[freesub]: https://azure.microsoft.com/free/
[package]: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search/README.md
[typescript]: https://www.typescriptlang.org/docs/home.html

Просмотреть файл

@ -0,0 +1,40 @@
{
"name": "azure-search-samples-ts",
"private": true,
"version": "0.1.0",
"description": "Azure Cognitive Search client library samples for TypeScript",
"engine": {
"node": ">=8.0.0"
},
"scripts": {
"build": "tsc",
"prebuild": "rimraf dist/"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Azure/azure-sdk-for-js.git"
},
"keywords": [
"Azure",
"Search",
"Node.js",
"TypeScript"
],
"author": "Microsoft Corporation",
"license": "MIT",
"bugs": {
"url": "https://github.com/Azure/azure-sdk-for-js/issues"
},
"homepage": "https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/search/search",
"sideEffects": false,
"dependencies": {
"@azure/search": "latest",
"@azure/identity": "latest",
"dotenv": "^8.2.0"
},
"devDependencies": {
"@types/node": "^8.0.0",
"rimraf": "^3.0.0",
"typescript": "~3.7.5"
}
}

Просмотреть файл

@ -0,0 +1,6 @@
# Used in most samples. Retrieve these values from a Cognitive Services instance
# in the Azure Portal.
SEARCH_API_KEY=<search api key>
SEARCH_API_ENDPOINT=https://<resource name>.search.windows.net
INDEX_NAME=hotels-sample-index

Просмотреть файл

@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* Performs a query over a public dataset
*/
import { SearchIndexClient, SearchApiKeyCredential, odata, GeographyPoint } from "@azure/search";
// Load the .env file if it exists
import * as dotenv from "dotenv";
dotenv.config();
interface Hotel {
HotelId: string;
HotelName: string;
Description: string;
Description_fr: string;
Category: string;
Tags: string[];
ParkingIncluded: boolean;
LastRenovationDate: Date;
Rating: number;
Address: {
StreetAddress: string;
City: string;
StateProvince: string;
PostalCode: string;
Country: string;
};
Location: GeographyPoint;
Rooms: Array<{
Description: string;
Description_fr: string;
Type: string;
BaseRate: number;
BedOptions: string;
SleepsCount: number;
SmokingAllowed: boolean;
Tags: string[];
}>;
}
export async function main() {
console.log(`Running readonly query sample`);
// Variables provided by https://docs.microsoft.com/en-us/samples/azure-samples/azure-search-sample-data/azure-search-sample-data/
const endpoint = "https://azs-playground.search.windows.net";
const apiKey = "EA4510A6219E14888741FCFC19BFBB82";
const indexName = "hotels";
const credential = new SearchApiKeyCredential(apiKey);
const client = new SearchIndexClient<Hotel>(endpoint, indexName, credential);
const count = await client.countDocuments();
console.log(`${count} documents in index ${client.indexName}`);
const state = "FL";
const country = "USA";
const searchResults = await client.search({
searchText: "WiFi",
filter: odata`Address/StateProvince eq ${state} and Address/Country eq ${country}`,
orderBy: ["Rating desc"],
select: ["HotelId", "HotelName", "Rating"]
});
for await (const result of searchResults.results) {
console.log(`${result.HotelName}: ${result.Rating} stars`);
}
}
main().catch((err) => {
console.error("The sample encountered an error:", err);
});

Просмотреть файл

@ -0,0 +1,16 @@
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"strict": true,
"alwaysStrict": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**.ts"],
"exclude": ["node_modules"]
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export const SDK_VERSION: string = "1.0.0-preview.1";
export const SDK_VERSION: string = "11.0.0-preview.1";

Просмотреть файл

@ -17,7 +17,7 @@ export interface SuggestResult {
* The text of the suggestion result.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly text?: string;
readonly text: string;
/**
* Describes unknown properties. The value of an unknown property can be of "any" type.
*/
@ -32,7 +32,7 @@ export interface SuggestDocumentsResult {
* The sequence of results returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results?: SuggestResult[];
readonly results: SuggestResult[];
/**
* A value indicating the percentage of the index that was included in the query, or null if
* minimumCoverage was not set in the request.
@ -166,7 +166,7 @@ export interface SearchResult {
* The relevance score of the document compared to other documents returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly score?: number;
readonly score: number;
/**
* Text fragments from the document that indicate the matching search terms, organized by each
* applicable field; null if hit highlighting was not enabled for the query.
@ -214,7 +214,7 @@ export interface SearchDocumentsResult {
* The sequence of results returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results?: SearchResult[];
readonly results: SearchResult[];
/**
* Continuation URL returned when Azure Cognitive Search can't return all the requested results
* in a single Search response. You can use this URL to formulate another GET or POST Search
@ -258,7 +258,7 @@ export interface IndexingResult {
* The key of a document that was in the indexing request.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly key?: string;
readonly key: string;
/**
* The error message explaining why the indexing operation failed for the document identified by
* the key; null if indexing succeeded.
@ -270,7 +270,7 @@ export interface IndexingResult {
* key.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly succeeded?: boolean;
readonly succeeded: boolean;
/**
* The status code of the indexing operation. Possible values include: 200 for a successful
* update or delete, 201 for successful document creation, 400 for a malformed input document,
@ -278,7 +278,7 @@ export interface IndexingResult {
* unavailable, or 503 for when the service is too busy.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly statusCode?: number;
readonly statusCode: number;
}
/**
@ -289,7 +289,7 @@ export interface IndexDocumentsResult {
* The list of status information for each document in the indexing request.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results?: IndexingResult[];
readonly results: IndexingResult[];
}
/**
@ -430,12 +430,12 @@ export interface AutocompleteItem {
* The completed term.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly text?: string;
readonly text: string;
/**
* The query along with the completed term.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly queryPlusText?: string;
readonly queryPlusText: string;
}
/**
@ -452,25 +452,28 @@ export interface AutocompleteResult {
* The list of returned Autocompleted items.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results?: AutocompleteItem[];
readonly results: AutocompleteItem[];
}
/**
* An interface representing SearchError.
* Describes an error condition for the Azure Cognitive Search API.
*/
export interface SearchError {
code: string;
message: string;
}
/**
* Additional parameters for a set of operations.
*/
export interface RequestOptions {
/**
* The tracking ID sent with the request to help with debugging.
* One of a server-defined set of error codes.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
clientRequestId?: string;
readonly code?: string;
/**
* A human-readable representation of the error.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly message: string;
/**
* An array of details about specific errors that led to this reported error.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly details?: SearchError[];
}
/**
@ -679,16 +682,6 @@ export interface AutocompleteOptions {
top?: number;
}
/**
* Optional Parameters.
*/
export interface DocumentsCountOptionalParams extends coreHttp.RequestOptionsBase {
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
* Optional Parameters.
*/
@ -701,20 +694,6 @@ export interface DocumentsSearchGetOptionalParams extends coreHttp.RequestOption
* Additional parameters for the operation
*/
searchOptions?: SearchOptions;
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
* Optional Parameters.
*/
export interface DocumentsSearchPostOptionalParams extends coreHttp.RequestOptionsBase {
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
@ -726,10 +705,6 @@ export interface DocumentsGetOptionalParams extends coreHttp.RequestOptionsBase
* the returned document.
*/
selectedFields?: string[];
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
@ -740,56 +715,18 @@ export interface DocumentsSuggestGetOptionalParams extends coreHttp.RequestOptio
* Additional parameters for the operation
*/
suggestOptions?: SuggestOptions;
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
* Optional Parameters.
*/
export interface DocumentsSuggestPostOptionalParams extends coreHttp.RequestOptionsBase {
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
* Optional Parameters.
*/
export interface DocumentsIndexOptionalParams extends coreHttp.RequestOptionsBase {
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
* Optional Parameters.
*/
export interface DocumentsAutocompleteGetOptionalParams extends coreHttp.RequestOptionsBase {
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
/**
* Additional parameters for the operation
*/
autocompleteOptions?: AutocompleteOptions;
}
/**
* Optional Parameters.
*/
export interface DocumentsAutocompletePostOptionalParams extends coreHttp.RequestOptionsBase {
/**
* Additional parameters for the operation
*/
requestOptions?: RequestOptions;
}
/**
* Defines values for QueryType.
* Possible values include: 'simple', 'full'

Просмотреть файл

@ -16,6 +16,7 @@ export const SuggestResult: coreHttp.CompositeMapper = {
className: "SuggestResult",
modelProperties: {
text: {
required: true,
readOnly: true,
serializedName: "@search\\.text",
type: {
@ -38,6 +39,7 @@ export const SuggestDocumentsResult: coreHttp.CompositeMapper = {
className: "SuggestDocumentsResult",
modelProperties: {
results: {
required: true,
readOnly: true,
serializedName: "value",
type: {
@ -225,6 +227,7 @@ export const SearchResult: coreHttp.CompositeMapper = {
className: "SearchResult",
modelProperties: {
score: {
required: true,
nullable: false,
readOnly: true,
serializedName: "@search\\.score",
@ -310,6 +313,7 @@ export const SearchDocumentsResult: coreHttp.CompositeMapper = {
}
},
results: {
required: true,
readOnly: true,
serializedName: "value",
type: {
@ -401,6 +405,7 @@ export const IndexingResult: coreHttp.CompositeMapper = {
className: "IndexingResult",
modelProperties: {
key: {
required: true,
readOnly: true,
serializedName: "key",
type: {
@ -415,6 +420,7 @@ export const IndexingResult: coreHttp.CompositeMapper = {
}
},
succeeded: {
required: true,
nullable: false,
readOnly: true,
serializedName: "status",
@ -423,6 +429,7 @@ export const IndexingResult: coreHttp.CompositeMapper = {
}
},
statusCode: {
required: true,
nullable: false,
readOnly: true,
serializedName: "statusCode",
@ -441,6 +448,7 @@ export const IndexDocumentsResult: coreHttp.CompositeMapper = {
className: "IndexDocumentsResult",
modelProperties: {
results: {
required: true,
readOnly: true,
serializedName: "value",
type: {
@ -619,6 +627,7 @@ export const AutocompleteItem: coreHttp.CompositeMapper = {
className: "AutocompleteItem",
modelProperties: {
text: {
required: true,
readOnly: true,
serializedName: "text",
type: {
@ -626,6 +635,7 @@ export const AutocompleteItem: coreHttp.CompositeMapper = {
}
},
queryPlusText: {
required: true,
readOnly: true,
serializedName: "queryPlusText",
type: {
@ -650,6 +660,7 @@ export const AutocompleteResult: coreHttp.CompositeMapper = {
}
},
results: {
required: true,
readOnly: true,
serializedName: "value",
type: {
@ -673,7 +684,7 @@ export const SearchError: coreHttp.CompositeMapper = {
className: "SearchError",
modelProperties: {
code: {
required: true,
readOnly: true,
serializedName: "code",
type: {
name: "String"
@ -681,23 +692,23 @@ export const SearchError: coreHttp.CompositeMapper = {
},
message: {
required: true,
readOnly: true,
serializedName: "message",
type: {
name: "String"
}
}
}
}
};
export const RequestOptions: coreHttp.CompositeMapper = {
type: {
name: "Composite",
className: "RequestOptions",
modelProperties: {
clientRequestId: {
},
details: {
readOnly: true,
serializedName: "details",
type: {
name: "Uuid"
name: "Sequence",
element: {
type: {
name: "Composite",
className: "SearchError"
}
}
}
}
}

Просмотреть файл

@ -38,24 +38,11 @@ export const autocompleteMode: coreHttp.OperationQueryParameter = {
}
}
};
export const clientRequestId: coreHttp.OperationParameter = {
parameterPath: [
"options",
"requestOptions",
"clientRequestId"
],
mapper: {
serializedName: "client-request-id",
type: {
name: "Uuid"
}
}
};
export const endpoint: coreHttp.OperationURLParameter = {
parameterPath: "endpoint",
mapper: {
required: true,
serializedName: "Endpoint",
serializedName: "endpoint",
defaultValue: '',
type: {
name: "String"

Просмотреть файл

@ -31,7 +31,7 @@ export class Documents {
* @param [options] The optional parameters
* @returns Promise<Models.DocumentsCountResponse>
*/
count(options?: Models.DocumentsCountOptionalParams): Promise<Models.DocumentsCountResponse>;
count(options?: coreHttp.RequestOptionsBase): Promise<Models.DocumentsCountResponse>;
/**
* @param callback The callback
*/
@ -40,8 +40,8 @@ export class Documents {
* @param options The optional parameters
* @param callback The callback
*/
count(options: Models.DocumentsCountOptionalParams, callback: coreHttp.ServiceCallback<number>): void;
count(options?: Models.DocumentsCountOptionalParams | coreHttp.ServiceCallback<number>, callback?: coreHttp.ServiceCallback<number>): Promise<Models.DocumentsCountResponse> {
count(options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback<number>): void;
count(options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback<number>, callback?: coreHttp.ServiceCallback<number>): Promise<Models.DocumentsCountResponse> {
return this.client.sendOperationRequest(
{
options
@ -80,7 +80,7 @@ export class Documents {
* @param [options] The optional parameters
* @returns Promise<Models.DocumentsSearchPostResponse>
*/
searchPost(searchRequest: Models.SearchRequest, options?: Models.DocumentsSearchPostOptionalParams): Promise<Models.DocumentsSearchPostResponse>;
searchPost(searchRequest: Models.SearchRequest, options?: coreHttp.RequestOptionsBase): Promise<Models.DocumentsSearchPostResponse>;
/**
* @param searchRequest The definition of the Search request.
* @param callback The callback
@ -91,8 +91,8 @@ export class Documents {
* @param options The optional parameters
* @param callback The callback
*/
searchPost(searchRequest: Models.SearchRequest, options: Models.DocumentsSearchPostOptionalParams, callback: coreHttp.ServiceCallback<Models.SearchDocumentsResult>): void;
searchPost(searchRequest: Models.SearchRequest, options?: Models.DocumentsSearchPostOptionalParams | coreHttp.ServiceCallback<Models.SearchDocumentsResult>, callback?: coreHttp.ServiceCallback<Models.SearchDocumentsResult>): Promise<Models.DocumentsSearchPostResponse> {
searchPost(searchRequest: Models.SearchRequest, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback<Models.SearchDocumentsResult>): void;
searchPost(searchRequest: Models.SearchRequest, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback<Models.SearchDocumentsResult>, callback?: coreHttp.ServiceCallback<Models.SearchDocumentsResult>): Promise<Models.DocumentsSearchPostResponse> {
return this.client.sendOperationRequest(
{
searchRequest,
@ -174,7 +174,7 @@ export class Documents {
* @param [options] The optional parameters
* @returns Promise<Models.DocumentsSuggestPostResponse>
*/
suggestPost(suggestRequest: Models.SuggestRequest, options?: Models.DocumentsSuggestPostOptionalParams): Promise<Models.DocumentsSuggestPostResponse>;
suggestPost(suggestRequest: Models.SuggestRequest, options?: coreHttp.RequestOptionsBase): Promise<Models.DocumentsSuggestPostResponse>;
/**
* @param suggestRequest The Suggest request.
* @param callback The callback
@ -185,8 +185,8 @@ export class Documents {
* @param options The optional parameters
* @param callback The callback
*/
suggestPost(suggestRequest: Models.SuggestRequest, options: Models.DocumentsSuggestPostOptionalParams, callback: coreHttp.ServiceCallback<Models.SuggestDocumentsResult>): void;
suggestPost(suggestRequest: Models.SuggestRequest, options?: Models.DocumentsSuggestPostOptionalParams | coreHttp.ServiceCallback<Models.SuggestDocumentsResult>, callback?: coreHttp.ServiceCallback<Models.SuggestDocumentsResult>): Promise<Models.DocumentsSuggestPostResponse> {
suggestPost(suggestRequest: Models.SuggestRequest, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback<Models.SuggestDocumentsResult>): void;
suggestPost(suggestRequest: Models.SuggestRequest, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback<Models.SuggestDocumentsResult>, callback?: coreHttp.ServiceCallback<Models.SuggestDocumentsResult>): Promise<Models.DocumentsSuggestPostResponse> {
return this.client.sendOperationRequest(
{
suggestRequest,
@ -202,7 +202,7 @@ export class Documents {
* @param [options] The optional parameters
* @returns Promise<Models.DocumentsIndexResponse>
*/
index(batch: Models.IndexBatch, options?: Models.DocumentsIndexOptionalParams): Promise<Models.DocumentsIndexResponse>;
index(batch: Models.IndexBatch, options?: coreHttp.RequestOptionsBase): Promise<Models.DocumentsIndexResponse>;
/**
* @param batch The batch of index actions.
* @param callback The callback
@ -213,8 +213,8 @@ export class Documents {
* @param options The optional parameters
* @param callback The callback
*/
index(batch: Models.IndexBatch, options: Models.DocumentsIndexOptionalParams, callback: coreHttp.ServiceCallback<Models.IndexDocumentsResult>): void;
index(batch: Models.IndexBatch, options?: Models.DocumentsIndexOptionalParams | coreHttp.ServiceCallback<Models.IndexDocumentsResult>, callback?: coreHttp.ServiceCallback<Models.IndexDocumentsResult>): Promise<Models.DocumentsIndexResponse> {
index(batch: Models.IndexBatch, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback<Models.IndexDocumentsResult>): void;
index(batch: Models.IndexBatch, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback<Models.IndexDocumentsResult>, callback?: coreHttp.ServiceCallback<Models.IndexDocumentsResult>): Promise<Models.DocumentsIndexResponse> {
return this.client.sendOperationRequest(
{
batch,
@ -265,7 +265,7 @@ export class Documents {
* @param [options] The optional parameters
* @returns Promise<Models.DocumentsAutocompletePostResponse>
*/
autocompletePost(autocompleteRequest: Models.AutocompleteRequest, options?: Models.DocumentsAutocompletePostOptionalParams): Promise<Models.DocumentsAutocompletePostResponse>;
autocompletePost(autocompleteRequest: Models.AutocompleteRequest, options?: coreHttp.RequestOptionsBase): Promise<Models.DocumentsAutocompletePostResponse>;
/**
* @param autocompleteRequest The definition of the Autocomplete request.
* @param callback The callback
@ -276,8 +276,8 @@ export class Documents {
* @param options The optional parameters
* @param callback The callback
*/
autocompletePost(autocompleteRequest: Models.AutocompleteRequest, options: Models.DocumentsAutocompletePostOptionalParams, callback: coreHttp.ServiceCallback<Models.AutocompleteResult>): void;
autocompletePost(autocompleteRequest: Models.AutocompleteRequest, options?: Models.DocumentsAutocompletePostOptionalParams | coreHttp.ServiceCallback<Models.AutocompleteResult>, callback?: coreHttp.ServiceCallback<Models.AutocompleteResult>): Promise<Models.DocumentsAutocompletePostResponse> {
autocompletePost(autocompleteRequest: Models.AutocompleteRequest, options: coreHttp.RequestOptionsBase, callback: coreHttp.ServiceCallback<Models.AutocompleteResult>): void;
autocompletePost(autocompleteRequest: Models.AutocompleteRequest, options?: coreHttp.RequestOptionsBase | coreHttp.ServiceCallback<Models.AutocompleteResult>, callback?: coreHttp.ServiceCallback<Models.AutocompleteResult>): Promise<Models.DocumentsAutocompletePostResponse> {
return this.client.sendOperationRequest(
{
autocompleteRequest,
@ -300,9 +300,6 @@ const countOperationSpec: coreHttp.OperationSpec = {
queryParameters: [
Parameters.apiVersion
],
headerParameters: [
Parameters.clientRequestId
],
responses: {
200: {
bodyMapper: {
@ -346,9 +343,6 @@ const searchGetOperationSpec: coreHttp.OperationSpec = {
Parameters.skip,
Parameters.top0
],
headerParameters: [
Parameters.clientRequestId
],
responses: {
200: {
bodyMapper: Mappers.SearchDocumentsResult
@ -370,9 +364,6 @@ const searchPostOperationSpec: coreHttp.OperationSpec = {
queryParameters: [
Parameters.apiVersion
],
headerParameters: [
Parameters.clientRequestId
],
requestBody: {
parameterPath: "searchRequest",
mapper: {
@ -403,9 +394,6 @@ const getOperationSpec: coreHttp.OperationSpec = {
Parameters.selectedFields,
Parameters.apiVersion
],
headerParameters: [
Parameters.clientRequestId
],
responses: {
200: {
bodyMapper: {
@ -443,9 +431,6 @@ const suggestGetOperationSpec: coreHttp.OperationSpec = {
Parameters.select1,
Parameters.top1
],
headerParameters: [
Parameters.clientRequestId
],
responses: {
200: {
bodyMapper: Mappers.SuggestDocumentsResult
@ -467,9 +452,6 @@ const suggestPostOperationSpec: coreHttp.OperationSpec = {
queryParameters: [
Parameters.apiVersion
],
headerParameters: [
Parameters.clientRequestId
],
requestBody: {
parameterPath: "suggestRequest",
mapper: {
@ -498,9 +480,6 @@ const indexOperationSpec: coreHttp.OperationSpec = {
queryParameters: [
Parameters.apiVersion
],
headerParameters: [
Parameters.clientRequestId
],
requestBody: {
parameterPath: "batch",
mapper: {
@ -542,9 +521,6 @@ const autocompleteGetOperationSpec: coreHttp.OperationSpec = {
Parameters.searchFields2,
Parameters.top2
],
headerParameters: [
Parameters.clientRequestId
],
responses: {
200: {
bodyMapper: Mappers.AutocompleteResult
@ -566,9 +542,6 @@ const autocompletePostOperationSpec: coreHttp.OperationSpec = {
queryParameters: [
Parameters.apiVersion
],
headerParameters: [
Parameters.clientRequestId
],
requestBody: {
parameterPath: "autocompleteRequest",
mapper: {

Просмотреть файл

@ -21,7 +21,7 @@ class SearchIndexClient extends SearchIndexClientContext {
/**
* Initializes a new instance of the SearchIndexClient class.
* @param apiVersion Client Api Version.
* @param endpoint Search API endpoint (protocol and hostname)
* @param endpoint The endpoint URL of the search service.
* @param indexName The name of the index.
* @param credentials Subscription credentials which uniquely identify client subscription.
* @param [options] The parameter options

Просмотреть файл

@ -11,7 +11,7 @@
import * as coreHttp from "@azure/core-http";
const packageName = "@azure/search";
const packageVersion = "1.0.0-preview.1";
const packageVersion = "11.0.0-preview.1";
export class SearchIndexClientContext extends coreHttp.ServiceClient {
apiVersion: string;
@ -22,7 +22,7 @@ export class SearchIndexClientContext extends coreHttp.ServiceClient {
/**
* Initializes a new instance of the SearchIndexClientContext class.
* @param apiVersion Client Api Version.
* @param endpoint Search API endpoint (protocol and hostname)
* @param endpoint The endpoint URL of the search service.
* @param indexName The name of the index.
* @param credentials Subscription credentials which uniquely identify client subscription.
* @param [options] The parameter options
@ -52,7 +52,7 @@ export class SearchIndexClientContext extends coreHttp.ServiceClient {
super(credentials, options);
this.baseUri = "{Endpoint}/indexes('{indexName}')";
this.baseUri = "{endpoint}/indexes('{indexName}')";
this.requestContentType = "application/json; charset=utf-8";
this.apiVersion = apiVersion;
this.endpoint = endpoint;

Просмотреть файл

@ -5,12 +5,15 @@ export { SearchIndexClient, SearchIndexClientOptions } from "./searchIndexClient
export {
AutocompleteRequest,
AutocompleteOptions,
CountOptions,
CountDocumentsOptions,
DeleteDocumentsOptions,
GetDocumentOptions,
IndexAction,
ListSearchResultsPageSettings,
ModifyIndexOptions,
IndexDocuments,
SearchDocumentsResultBase,
SearchDocumentsResult,
SearchDocumentsPageResult,
SearchIterator,
SearchOptions,
SearchRequest,
@ -19,7 +22,7 @@ export {
SuggestRequest,
SuggestResult,
SuggestOptions,
UpdateDocumentsOptions,
MergeDocumentsOptions,
UploadDocumentsOptions
} from "./models";
export { SearchApiKeyCredential } from "./searchApiKeyCredential";
@ -30,10 +33,10 @@ export {
AutocompleteMode,
AutocompleteItem,
FacetResult,
IndexAction,
IndexActionType,
IndexDocumentsResult,
IndexingResult,
QueryType,
SearchMode
SearchMode,
SearchRequest as RawSearchRequest
} from "./generated/data/models";

Просмотреть файл

@ -2,13 +2,20 @@
// Licensed under the MIT license.
import { OperationOptions } from "@azure/core-http";
import { QueryType, SearchMode, FacetResult, AutocompleteMode } from "./generated/data/models";
import {
QueryType,
SearchMode,
FacetResult,
AutocompleteMode,
IndexActionType,
SearchRequest as RawSearchRequest
} from "./generated/data/models";
import { PagedAsyncIterableIterator } from "@azure/core-paging";
/**
* Options for performing the count operation on the index.
*/
export type CountOptions = OperationOptions;
export type CountDocumentsOptions = OperationOptions;
/**
* Options for retrieving completion text for a partial searchText.
*/
@ -36,7 +43,7 @@ export interface GetDocumentOptions<Fields> extends OperationOptions {
/**
* Options for the modify index batch operation.
*/
export interface ModifyIndexOptions extends OperationOptions {
export interface IndexDocuments extends OperationOptions {
/**
* If true, will cause this operation to throw if any document operation
* in the batch did not succeed.
@ -47,7 +54,7 @@ export interface ModifyIndexOptions extends OperationOptions {
/**
* Options for the upload documents operation.
*/
export interface UploadDocumentsOptions extends ModifyIndexOptions {
export interface UploadDocumentsOptions extends IndexDocuments {
/**
* If true, any documents in this batch will merge with existing documents
* which have the same primary key.
@ -58,7 +65,7 @@ export interface UploadDocumentsOptions extends ModifyIndexOptions {
/**
* Options for the update documents operation.
*/
export interface UpdateDocumentsOptions extends ModifyIndexOptions {
export interface MergeDocumentsOptions extends IndexDocuments {
/**
* If true, any documents in this batch that do not exist on the server
* will be treated as an upload instead of an update.
@ -69,7 +76,7 @@ export interface UpdateDocumentsOptions extends ModifyIndexOptions {
/**
* Options for the delete documents operation.
*/
export type DeleteDocumentsOptions = ModifyIndexOptions;
export type DeleteDocumentsOptions = IndexDocuments;
/**
* Arguments for retrieving the next page of search results.
@ -82,16 +89,17 @@ export interface ListSearchResultsPageSettings {
/**
* When server pagination occurs, this is the set of parameters to include in the POST body.
*/
nextPageParameters?: SearchRequest<string>;
nextPageParameters?: RawSearchRequest;
}
/**
* An iterator for search results of a paticular query. Use .byPage()
* to view page-level information such as facet data.
* An iterator for search results of a paticular query. Will make requests
* as needed during iteration. Use .byPage() to make one request to the server
* per iteration.
*/
export type SearchIterator<Fields> = PagedAsyncIterableIterator<
SearchResult<Fields>,
SearchDocumentsResult<Fields>,
SearchDocumentsPageResult<Fields>,
ListSearchResultsPageSettings
>;
@ -142,14 +150,14 @@ export interface SearchRequest<Fields> {
*/
minimumCoverage?: number;
/**
* The comma-separated list of OData $orderby expressions by which to sort the results. Each
* 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.
*/
orderBy?: string;
orderBy?: string[];
/**
* A value that specifies the syntax of the search query. The default is 'simple'. Use 'full' if
* your query uses the Lucene query syntax. Possible values include: 'simple', 'full'
@ -210,7 +218,7 @@ export type SearchResult<T> = {
* The relevance score of the document compared to other documents returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly score?: number;
readonly score: number;
/**
* Text fragments from the document that indicate the matching search terms, organized by each
* applicable field; null if hit highlighting was not enabled for the query.
@ -222,7 +230,7 @@ export type SearchResult<T> = {
/**
* Response containing search results from an index.
*/
export interface SearchDocumentsResult<T> {
export interface SearchDocumentsResultBase {
/**
* The total count of results found by the search operation, or null if the count was not
* requested. If present, the count may be greater than the number of results in this response.
@ -243,18 +251,29 @@ export interface SearchDocumentsResult<T> {
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly facets?: { [propertyName: string]: FacetResult[] };
}
export interface SearchDocumentsResult<T> extends SearchDocumentsResultBase {
/**
* The sequence of results returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results: SearchIterator<T>;
}
export interface SearchDocumentsPageResult<T> extends SearchDocumentsResultBase {
/**
* The sequence of results returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results: SearchResult<T>[];
/**
* Continuation JSON payload returned when Azure Cognitive Search can't return all the requested
* results in a single Search response. You can use this JSON along with @odata.nextLink to
* formulate another POST Search request to get the next part of the search response.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly nextPageParameters?: SearchRequest<string>;
/**
* The sequence of results returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results?: SearchResult<T>[];
readonly nextPageParameters?: RawSearchRequest;
/**
* Continuation URL returned when Azure Cognitive Search can't return all the requested results
* in a single Search response. You can use this URL to formulate another GET or POST Search
@ -299,14 +318,14 @@ export interface SuggestRequest<Fields> {
*/
minimumCoverage?: number;
/**
* The comma-separated list of OData $orderby expressions by which to sort the results. Each
* 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.
*/
orderBy?: string;
orderBy?: string[];
/**
* The search text to use to suggest documents. Must be at least 1 character, and no more than
* 100 characters.
@ -342,7 +361,7 @@ export type SuggestResult<T> = {
* The text of the suggestion result.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly text?: string;
readonly text: string;
} & T;
/**
@ -353,7 +372,7 @@ export interface SuggestDocumentsResult<T> {
* The sequence of results returned by the query.
* **NOTE: This property will not be serialized. It can only be populated by the server.**
*/
readonly results?: SuggestResult<T>[];
readonly results: SuggestResult<T>[];
/**
* A value indicating the percentage of the index that was included in the query, or null if
* minimumCoverage was not set in the request.
@ -423,4 +442,15 @@ export interface AutocompleteRequest<Fields> {
top?: number;
}
/**
* Represents an index action that operates on a document.
*/
export type IndexAction<T> = {
/**
* The operation to perform on a document in an indexing batch. Possible values include:
* 'upload', 'merge', 'mergeOrUpload', 'delete'
*/
actionType: IndexActionType;
} & Partial<T>;
// END manually modified generated interfaces

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import {
RequestPolicy,
RequestPolicyOptions,
BaseRequestPolicy,
WebResource,
HttpOperationResponse,
RequestPolicyFactory
} from "@azure/core-http";
const AcceptHeaderName = "Accept";
const AcceptHeaderValue = "application/json;odata.metadata=none";
/**
* A policy factory for setting the Accept header to ignore odata metadata
* @internal
* @ignore
*/
export function odataMetadataPolicy(): RequestPolicyFactory {
return {
create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions) => {
return new OdataMetadataPolicy(nextPolicy, options);
}
};
}
class OdataMetadataPolicy extends BaseRequestPolicy {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(
nextPolicy: RequestPolicy,
// eslint-disable-next-line @azure/azure-sdk/ts-use-interface-parameters
options: RequestPolicyOptions
) {
super(nextPolicy, options);
}
// eslint-disable-next-line @azure/azure-sdk/ts-use-interface-parameters
public async sendRequest(webResource: WebResource): Promise<HttpOperationResponse> {
webResource.headers.set(AcceptHeaderName, AcceptHeaderValue);
return this._nextPolicy.sendRequest(webResource);
}
}

Просмотреть файл

@ -20,14 +20,14 @@ import {
AutocompleteRequest,
SearchRequest,
SuggestRequest,
IndexAction,
IndexDocumentsResult
} from "./generated/data/models";
import { createSpan } from "./tracing";
import { CanonicalCode } from "@opentelemetry/types";
import { deserialize, serialize } from "./serialization";
import {
CountOptions,
IndexAction,
CountDocumentsOptions,
AutocompleteOptions,
SearchOptions,
SearchDocumentsResult,
@ -37,11 +37,13 @@ import {
SuggestOptions,
SuggestDocumentsResult,
GetDocumentOptions,
ModifyIndexOptions,
IndexDocuments,
UploadDocumentsOptions,
UpdateDocumentsOptions,
DeleteDocumentsOptions
MergeDocumentsOptions,
DeleteDocumentsOptions,
SearchDocumentsPageResult
} from "./models";
import { odataMetadataPolicy } from "./odataMetadataPolicy";
/**
* Client options used to configure Cognitive Search API requests.
@ -137,6 +139,9 @@ export class SearchIndexClient<T> {
};
const pipeline = createPipelineFromOptions(internalPipelineOptions, signingPolicy(credential));
if (Array.isArray(pipeline.requestPolicyFactories)) {
pipeline.requestPolicyFactories.unshift(odataMetadataPolicy());
}
this.client = new GeneratedClient(
credential,
this.apiVersion,
@ -150,8 +155,8 @@ export class SearchIndexClient<T> {
* Retrieves the number of documents in the index.
* @param options Options to the count operation.
*/
public async count(options: CountOptions = {}): Promise<number> {
const { span, updatedOptions } = createSpan("SearchIndexClient-count", options);
public async countDocuments(options: CountDocumentsOptions = {}): Promise<number> {
const { span, updatedOptions } = createSpan("SearchIndexClient-countDocuments", options);
try {
const result = await this.client.documents.count(
operationOptionsToRequestOptionsBase(updatedOptions)
@ -210,25 +215,31 @@ export class SearchIndexClient<T> {
}
}
private async search<Fields extends keyof T>(
options: SearchOptions<Fields> = {}
): Promise<SearchDocumentsResult<Pick<T, Fields>>> {
private async searchDocuments<Fields extends keyof T>(
options: SearchOptions<Fields> = {},
nextPageParameters: SearchRequest = {}
): Promise<SearchDocumentsPageResult<Pick<T, Fields>>> {
const { operationOptions, restOptions } = this.extractOperationOptions({ ...options });
const { select, searchFields, ...nonFieldOptions } = restOptions;
const { select, searchFields, orderBy, ...nonFieldOptions } = restOptions;
const fullOptions: SearchRequest = {
searchFields: this.convertSearchFields<Fields>(searchFields),
select: this.convertSelect<Fields>(select),
...nonFieldOptions
orderBy: this.convertOrderBy(orderBy),
...nonFieldOptions,
...nextPageParameters
};
const { span, updatedOptions } = createSpan("SearchIndexClient-search", operationOptions);
const { span, updatedOptions } = createSpan(
"SearchIndexClient-searchDocuments",
operationOptions
);
try {
const result = await this.client.documents.searchPost(
fullOptions,
operationOptionsToRequestOptionsBase(updatedOptions)
);
return deserialize<SearchDocumentsResult<Pick<T, Fields>>>(result);
return deserialize<SearchDocumentsPageResult<Pick<T, Fields>>>(result);
} catch (e) {
span.setStatus({
code: CanonicalCode.UNKNOWN,
@ -243,43 +254,39 @@ export class SearchIndexClient<T> {
private async *listSearchResultsPage<Fields extends keyof T>(
options: SearchOptions<Fields> = {},
settings: ListSearchResultsPageSettings = {}
): AsyncIterableIterator<SearchDocumentsResult<Pick<T, Fields>>> {
let result = await this.search<Fields>({
...options,
...(settings.nextPageParameters as any)
});
): AsyncIterableIterator<SearchDocumentsPageResult<Pick<T, Fields>>> {
let result = await this.searchDocuments<Fields>(options, settings.nextPageParameters);
yield result;
// Technically, we should also leverage nextLink, but the generated code
// doesn't support this yet.
while (result.nextPageParameters) {
result = await this.search({
...options,
...(result.nextPageParameters as any)
});
result = await this.searchDocuments(options, result.nextPageParameters);
yield result;
}
}
private async *listSearchResultsAll<Fields extends keyof T>(
firstPage: SearchDocumentsPageResult<Pick<T, Fields>>,
options: SearchOptions<Fields> = {}
): AsyncIterableIterator<SearchResult<T>> {
for await (const page of this.listSearchResultsPage(options)) {
const results: Array<SearchResult<T>> = (page.results as any) || [];
yield* results;
): AsyncIterableIterator<SearchResult<Pick<T, Fields>>> {
yield* firstPage.results;
if (firstPage.nextPageParameters) {
for await (const page of this.listSearchResultsPage(options, {
nextLink: firstPage.nextLink,
nextPageParameters: firstPage.nextPageParameters
})) {
yield* page.results;
}
}
}
/**
* Performs a search on the current index given
* the specified arguments.
* @param options Options for the search operation.
*/
public listSearchResults<Fields extends keyof T>(
private listSearchResults<Fields extends keyof T>(
firstPage: SearchDocumentsPageResult<Pick<T, Fields>>,
options: SearchOptions<Fields> = {}
): SearchIterator<Pick<T, Fields>> {
const iter = this.listSearchResultsAll(options);
const iter = this.listSearchResultsAll(firstPage, options);
return {
next() {
@ -294,19 +301,51 @@ export class SearchIndexClient<T> {
};
}
/**
* Performs a search on the current index given
* the specified arguments.
* @param options Options for the search operation.
*/
public async search<Fields extends keyof T>(
options: SearchOptions<Fields> = {}
): Promise<SearchDocumentsResult<Pick<T, Fields>>> {
const { span, updatedOptions } = createSpan("SearchIndexClient-search", options);
try {
const pageResult = await this.searchDocuments(updatedOptions);
const { count, coverage, facets } = pageResult;
return {
count,
coverage,
facets,
results: this.listSearchResults(pageResult, updatedOptions)
};
} catch (e) {
span.setStatus({
code: CanonicalCode.UNKNOWN,
message: e.message
});
throw e;
} finally {
span.end();
}
}
/**
* Returns a short list of suggestions based on the searchText
* and specified suggester.
* @param options Options for the suggest operation
*/
public async suggest<Fields extends keyof T>(
public async suggest<Fields extends keyof T = never>(
options: SuggestOptions<Fields>
): Promise<SuggestDocumentsResult<Pick<T, Fields>>> {
const { operationOptions, restOptions } = this.extractOperationOptions({ ...options });
const { select, searchFields, ...nonFieldOptions } = restOptions;
const { select, searchFields, orderBy, ...nonFieldOptions } = restOptions;
const fullOptions: SuggestRequest = {
searchFields: this.convertSearchFields<Fields>(searchFields),
select: this.convertSelect<Fields>(select),
orderBy: this.convertOrderBy(orderBy),
...nonFieldOptions
};
@ -374,11 +413,11 @@ export class SearchIndexClient<T> {
* @param batch An array of actions to perform on the index.
* @param options Additional options.
*/
public async modifyIndex(
batch: IndexAction[],
options: ModifyIndexOptions = {}
public async indexDocuments(
batch: IndexAction<T>[],
options: IndexDocuments = {}
): Promise<IndexDocumentsResult> {
const { span, updatedOptions } = createSpan("SearchIndexClient-modifyIndex", options);
const { span, updatedOptions } = createSpan("SearchIndexClient-indexDocuments", options);
try {
const result = await this.client.documents.index(
{ actions: serialize(batch) },
@ -411,7 +450,7 @@ export class SearchIndexClient<T> {
const actionType = options.mergeIfExists ? "mergeOrUpload" : "upload";
const { span, updatedOptions } = createSpan("SearchIndexClient-uploadDocuments", options);
const batch = documents.map<IndexAction>((doc) => {
const batch = documents.map<IndexAction<T>>((doc) => {
return {
...doc,
actionType
@ -419,7 +458,7 @@ export class SearchIndexClient<T> {
});
try {
return await this.modifyIndex(batch, updatedOptions);
return await this.indexDocuments(batch, updatedOptions);
} catch (e) {
span.setStatus({
code: CanonicalCode.UNKNOWN,
@ -437,14 +476,14 @@ export class SearchIndexClient<T> {
* @param documents The updated documents.
* @param options Additional options.
*/
public async updateDocuments(
public async mergeDocuments(
documents: T[],
options: UpdateDocumentsOptions = {}
options: MergeDocumentsOptions = {}
): Promise<IndexDocumentsResult> {
const actionType = options.uploadIfNotExists ? "mergeOrUpload" : "merge";
const { span, updatedOptions } = createSpan("SearchIndexClient-updateDocuments", options);
const { span, updatedOptions } = createSpan("SearchIndexClient-mergeDocuments", options);
const batch = documents.map<IndexAction>((doc) => {
const batch = documents.map<IndexAction<T>>((doc) => {
return {
...doc,
actionType
@ -452,7 +491,7 @@ export class SearchIndexClient<T> {
});
try {
return await this.modifyIndex(batch, updatedOptions);
return await this.indexDocuments(batch, updatedOptions);
} catch (e) {
span.setStatus({
code: CanonicalCode.UNKNOWN,
@ -471,20 +510,20 @@ export class SearchIndexClient<T> {
* @param options Additional options.
*/
public async deleteDocuments(
keyName: string,
keyName: keyof T,
keyValues: string[],
options: DeleteDocumentsOptions = {}
): Promise<IndexDocumentsResult> {
const { span, updatedOptions } = createSpan("SearchIndexClient-deleteDocuments", options);
const batch = keyValues.map<IndexAction>((keyValue) => {
const batch = keyValues.map<IndexAction<T>>((keyValue) => {
return {
actionType: "delete",
[keyName]: keyValue
};
} as IndexAction<T>;
});
try {
return await this.modifyIndex(batch, updatedOptions);
return await this.indexDocuments(batch, updatedOptions);
} catch (e) {
span.setStatus({
code: CanonicalCode.UNKNOWN,
@ -527,4 +566,11 @@ export class SearchIndexClient<T> {
}
return searchFields;
}
private convertOrderBy(orderBy?: string[]): string | undefined {
if (orderBy) {
return orderBy.join(",");
}
return orderBy;
}
}

Просмотреть файл

@ -10,7 +10,7 @@ generate-metadata: false
license-header: MICROSOFT_MIT_NO_VERSION
output-folder: ../
source-code-folder-path: ./src/generated/data
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/search/data-plane/Microsoft.Azure.Search.Data/stable/2019-05-06/searchindex.json
input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/search/data-plane/Azure.Search/preview/2019-05-06-preview/searchindex.json
add-credentials: true
use-extension:
"@microsoft.azure/autorest.typescript": "5.0.1"
@ -21,66 +21,28 @@ use-extension:
See the [AutoRest samples](https://github.com/Azure/autorest/tree/master/Samples/3b-custom-transformations)
for more about how we're customizing things.
### Move to endpoint
### Remove duplicate header parameter
```yaml
directive:
- from: swagger-document
where: $['x-ms-parameterized-host']
where: $.paths..post
transform: >
$["hostTemplate"] = "{Endpoint}/indexes('{indexName}')";
$.parameters = [{"$ref": "#/parameters/Endpoint"},{"$ref": "#/parameters/IndexNameParameter"}]
- from: swagger-document
where: $.parameters
transform: >
delete $.SearchServiceNameParameter;
delete $.SearchDnsSuffixParameter;
$.Endpoint = {};
$.Endpoint.name = "Endpoint";
$.Endpoint.in = "path";
$.Endpoint.required = true;
$.Endpoint.type = "string";
$.Endpoint["x-ms-skip-url-encoding"] = true;
$.Endpoint["description"] = "Search API endpoint (protocol and hostname)";
$.Endpoint["x-ms-parameter-location"] = "client";
const indexName = $.IndexNameParameter;
delete $.IndexNameParameter;
$.IndexNameParameter = indexName;
```
### Give us a default handler
```yaml
directive:
- from: swagger-document
where: $.paths..responses
transform: >
if (!$["default"]) {
$["default"] = {};
$["default"].description = "Error Response";
$["default"].schema = {"$ref": "#/definitions/SearchError"};
const newParameters = [];
for (let param of $.parameters) {
if (param["$ref"] !== "#/parameters/ClientRequestIdParameter") {
newParameters.push(param);
}
}
$.parameters = newParameters;
- from: swagger-document
where: $.definitions
where: $.paths..get
transform: >
$["SearchError"] = {};
$["SearchError"].type = "object";
$["SearchError"].required = ["code", "message"];
$["SearchError"].properties = {};
$["SearchError"].properties.code = { type: "string" };
$["SearchError"].properties.message = { type: "string" };
```
### Mark properties as required
```yaml
directive:
- from: swagger-document
where: $.definitions.AutocompleteRequest
transform: >
$.required = ["search", "suggesterName"]
- from: swagger-document
where: $.definitions.SuggestRequest
transform: >
$.required = ["search", "suggesterName"]
const newParameters = [];
for (let param of $.parameters) {
if (param["$ref"] !== "#/parameters/ClientRequestIdParameter") {
newParameters.push(param);
}
}
$.parameters = newParameters;
```