0.0.1 • Published 6 years ago

asc-test v0.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
6 years ago

Installation

npm install azure-search-client

Usage

Basic query (async/await)

Responses may be retrieved using the async/await pattern:

const { SearchService } = require('azure-search-client');

const client = new SearchService('myService', 'myKey');
const resp = await client.indexes.use('myIndex').search({
  search: 'hello world',
});
console.log(resp.result.value); // array of result docs

Basic query (callback)

Or Responses may be retrieved using the Node callback pattern:

client.indexes.use('myIndex').search({
  search: 'hello world',
}, (err, resp) => {
  if (err) { throw err; }
  console.log(resp.result.value); // array of result docs
});

Full query API

Use the Azure Search POST query representation

If you are using TypeScript see how to use your own document models on index operations.

client.indexes.use('myIndex').search({
  count: true,
  facets: ['field1', 'field2'],
  filter: `field1 eq 123 and field2 ne 'foo'`,
  highlight: 'field1, field2',
  highlightPreTag: '<b>',
  highlightPostTag: '</b>',
  minimumCoverage: 90,
  orderby: 'field1 desc, field2',
  scoringProfile: 'myProfile',
  scoringParameters: [
    "currentLocation--122.123,44.77233",
    "lastLocation--121.499,44.2113"
  ],
  search: 'hello world',
  searchFields: 'field1, field2',
  searchMode: 'any',
  select: 'field1, field2',
  queryType: 'simple',
  skip: 0,
  top: 10,
});

Query builders

Use QueryBuilder, FilterBuilder, FacetBuilder, and LambdaQueryFilter helpers to build a query using method chaining.

client.indexes.use('myIndex')
  .buildQuery()
  .count(true)
  .buildFacet('field1', (facet) => facet
    .count(20)
    .sortByValue('desc'))
  .facet('field2', 'field3', new FacetBuilder('field4').count(20)) // can combine .buildFacet with .facet
  .buildFilter((filter) => filter
    .eq('field1', 123)
    .any('myCollection', (lambda) => lambda.in('a', 'b', 'c'))
    .geoDistance('myGeo', [122, 80], GeoComparison.lt, 10)
    .eq('field2', 'foo'))
  // .filter(`field1 eq 'whatever'`) // use .buildFilter or .filter
  .highlight('field1', 'field2')
  .highlightTag('<b>', '</b>')
  .minimumCoverage(90)
  .orderbyAsc('field1')
  .orderByGeoDistance('geoField', [122, 80])
  .orderByScore()
  .scoringProfile('myProfile')
  .scoringParameter('currentLocation', '-122.123', '44.77233')
  .scoringParameter('lastLocation', '-121.499', '44.2113')
  .search('hello world')
  .searchFields('field1', 'field2')
  .searchMode('any')
  .select('field1', 'field2')
  .queryType('simple')
  .skip(0)
  .top(10)
  // .query // use .query to retrieve the query object or call .executeQuery() to retrieve results
  .executeQuery();

Strongly typed versions of these utilites are also available. See TypeScript Generics

Options

You can set optional request-specific options for any request:

client.indexes.use('myIndex').search({
  search: 'hello',
}, {
  version: 'thisRequestApiVersion',
  key: 'thisRequestKey',
  retry: 3,
  timeout: 10000,
  clientRequestId: '{guid}',
  returnClientRequestId: true,
  ifMatch: 'someEtag',
  ifNoneMatch: 'someEtag',
});

You can set the default API version for your client:

const client = new SearchService('myService', 'myKey', 'myDefaultApiVersion');

JSON has no date representation, so Azure Search returns Date fields as strings. The search client will automatically parse any string value that looks like a date. You can disable automatic date parsing in the request options:

client.indexes.use('myIndex').search({
  search: 'hello world',
}, {
  parseDates: false,
});

Any object with a list() function accepts an optional $select option to limit the fields that are fetched:

client.indexes.list({ $select: ['name1', 'name2'] });

Response properties

Every API response has some common properties (not every property is available for every request):

const resp = await client.indexes.use('myIndex').search({
  search: 'hello world',
});

// response body
resp.result;

// request id
resp.properties.requestId;

// time spent by the search engine
resp.properties.elapsedTime

// an identifier specified by the caller in the original request, if present
resp.properties.clientRequestId

// An opaque string representing the current version of a resource (returned for indexers, indexes, and data sources, but not documents). Use this string in the If-Match or If-None-Match header for optimistic concurrency control.
resp.properties.eTag

// The URL of the newly-created index definition for POST and PUT /indexes requests.
resp.properties.location

// HTTP status code of the current request
resp.statusCode

// Timestamp when the request started
resp.timer.start

// Node `hrtime` until the response headers arrived
resp.timer.response

// Node `hrtime` until the full response body was read
resp.timer.end

Manage search resources

With an admin key, the search client can manage the search resources

Manage Indexes

const indexes = client.indexes;

// CREATE INDEX
await indexes.create({
  /* IndexSchema */
});

// UPDATE INDEX
await indexes.update({
  /* IndexSchema */
});

// LIST INDEXES
await indexes.list();

Manage an index

const index = client.indexes.use('myIndex');

// ANALYZE TEXT
await index.analyze({
  /* AnalyzeQuery */
});

// COUNT DOCUMENTS
await index.count();

// DELETE THE INDEX
await index.delete();

// GET THE SCHEMA
await index.get();

// INDEX DOCUMENTS (add/update/delete)
await index.index([
  /* IndexDocument */
]);

// LOOKUP DOCUMENT
await index.lookup('myKey');

// SEARCH DOCUMENTS
await index.search({
  /* Query */
});

// GET INDEX STATS
await index.statistics();

// SUGGEST DOCUMENTS
await index.suggest({
  /* SuggestQuery */
});

Note: search, suggest, and lookup APIs will automatically parse document fields that look like Dates, returning JavaScript Date objects instead. To disable this, use the parseDate option


Manage Data Sources

const dataSources = client.dataSources;

// dataSources => .create, .update, .list

Manage a Data Source

const dataSource = client.dataSources.use('myDataSource');

// dataSource => .get, .delete

Manage Indexers

const indexers = client.indexers;

// indexers => .create, .update, .list

Manage an Indexer

const indexer = client.indexers.use('myIndexer');

// indexer => .get, .delete

// RESET INDEXER STATE
await indexer.reset();

// RUN THE INDEXER
await indexer.run();

// GET CURRENT INDEXER STATUS
await indexer.status();

Manage Synonym Maps

const synonymMaps = client.synonymMaps;

// synonymMaps => .create, .update, .list

Manage a Synonym Map

const synonymMap = client.synonymMap.use('mySynonymMap');

// synonymMap => .get, .delete

TypeScript Generics

If you are using TypeScript, this module can support your custom document types (strongly typed documents are optional).

import { SearchService } from 'azure-search-client';

interface MyDoc {
  id: string;
  num: number;
}

const resp = await client.indexes.use<MyDoc>('myIndex').search({
  search: 'hello',
});
const doc = resp.result.value[0];

doc is typed as MyDoc & SearchDocument, giving you compile-time access to id and num properties, as well as @search.score and @search.highlights.

Use your own Document types wherever documents are used: indexing, search, suggest.

If you omit the generic parameter, the default document type is IDocument which allows for arbitrary document fields.


When using a generic TDocument parameter on your SearchIndex, type safety also applies to the QueryBuilder, QueryFilter, and FacetBuilder utilities.

import { FacetBuilder, QueryBuilder, QueryFilter  } from 'azure-search-client';

interface MyDoc {
  id: string;
  num: number;
  date: Date;
  content: string;
}

const index = client.use<MyDoc>('myIndex');

const query = index.buildQuery() // or new QueryBuilder<MyDoc>()
    .searchFields('content') // ok
    .facet('num') // ok

    // these cause compile errors since 'blah' and 'foo' are not part of the document model
    .buildFacet('blah', (facet) => facet.count(20))
    .select('id', 'foo')
    .highlight('foo')
    .orderbyAsc('foo');

const filter = query.buildFilter((filter) => filter // or new QueryFilter<MyDoc>()
  .eq('id', 'foo') // ok
  .lt('date', new Date()) // ok
  .eq('num', 'oops, a string'); // compile failure: string is not assignable to number field