Skip to content

Commit

Permalink
feat: added sample script for multisearch (#657)
Browse files Browse the repository at this point in the history
* feat: added sample script for multisearch

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* update: changelog

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* feat: msearch guide

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* update: filename and license header

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* fix: msearch intro and code

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* fix: PR link

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* update: msearch code snippets

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* fix: changelog order

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

* update: user_guide with msearch

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>

---------

Signed-off-by: tejeshreddy <tejeshreddy111@gmail.com>
Signed-off-by: Tejesh Reddy <tejeshreddy111@gmail.com>
  • Loading branch information
tejeshreddy authored Dec 7, 2023
1 parent 8155a9d commit 9d3524b
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Added deprecation warnings for Index Template APIs ([654](https://github.com/opensearch-project/opensearch-js/pull/645))
- Added `http` functions: `connect`, `delete`, `get`, `head`, `options`, `patch`, `post`, `put`, and `trace` ([#649](https://github.com/opensearch-project/opensearch-js/pull/649))
- Added `samples/search.js` and updated `guides/search.md` to provide example to search functionality ([#656](https://github.com/opensearch-project/opensearch-js/pull/656))
- Added `samples/msearch.js` and `guides/msearch.md` to provide example to multi-search functionality ([#657](https://github.com/opensearch-project/opensearch-js/pull/657))
### Dependencies
- Bumps `@aws-sdk/types` from 3.418.0 to 3.451.0
- Bumps `@types/node` from 20.6.5 to 20.9.0
Expand Down
31 changes: 30 additions & 1 deletion USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
- [Authenticate with Amazon OpenSearch Service](#authenticate-with-amazon-opensearch-service)
- [Using AWS V2 SDK](#using-aws-v2-sdk)
- [Using AWS V3 SDK](#using-aws-v3-sdk)
- [Enable Handling of Long Numerals](#enable-handling-of-long-numerals)
- [Enable Handling of Long Numerals](#enable-handling-of-long-numerals)
- [Create an Index](#create-an-index)
- [Add a Document to the Index](#add-a-document-to-the-index)
- [Search for the Document](#search-for-the-document)
- [Multi-Search (msearch)](#multi-search-msearch)
- [Delete the document](#delete-the-document)
- [Delete the index](#delete-the-index)
- [Create a Point in Time](#create-a-point-in-time)
- [Get all PITs](#get-all-pits)
- [Delete a Point in Time](#delete-a-point-in-time)
- [Delete all PITs](#delete-all-pits)
- [Empty all Pool Connections](#empty-all-pool-connections)

## Initializing a Client
Expand Down Expand Up @@ -194,6 +199,30 @@ var response = await client.search({
console.log(response.body.hits);
```

## Multi-Search (msearch)

```javascript
const queries = [
{},
{ query: { match: { author: 'Stephen King' } } },
{},
{ query: { match: { title: 'The Outsider' } } },
];

const multiSearchResponse = await client.msearch({
index: index_name,
body: queries,
});

multiSearchResponse.body.responses.map((res) =>
res.hits.hits.map((movie) => {
console.log(movie._source);
})
);
```

Explore `msearch` further with a detailed guide in [msearch.md](guides/msearch.md) and find sample code in [msearch.js](samples/msearch.js).

## Delete the document

```javascript
Expand Down
66 changes: 66 additions & 0 deletions guides/msearch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Multi-Search (msearch)

OpenSearch's Multi-Search (`msearch`) API allows you to execute multiple search operations for documents within an index efficiently. This API supports various parameters that provide flexibility in customizing your search operations. It's crucial to understand the key differences between `msearch` and a regular `search` operation in OpenSearch. Unlike a single search operation, `msearch` enables you to perform multiple searches in a single API call, significantly reducing network overhead as it need not initialize a new network connection for each search. This proves particularly advantageous for batch operations or scenarios where searches span multiple indices. By combining searches into one request, `msearch` streamlines the process and enhances overall efficiency. However, it's important to note that there will also be a bit more memory overhead in the `msearch`, as the coordinating node will have to accumulate the various search responses in memory before sending back the final response. Explore the functionalities of the msearch API with the provided sample code in [../samples/msearch.js](../samples/msearch.js).

# Setup

```javascript
const host = "localhost";
const protocol = "https";
const port = 9200;
const auth = "admin:admin";
const ca_certs_path = "/full/path/to/root-ca.pem";
const { Client } = require("@opensearch-project/opensearch");
const fs = require("fs");
const client = new Client({
node: `${protocol}://${auth}@${host}:${port}`,
ssl: {
ca: fs.readFileSync(ca_certs_path),
},
});

await client.bulk({
body: [
{ index: { _index: 'movies', _id: 1 } },
{ title: 'The Godfather', director: 'Francis Ford Coppola', year: 1972 },
{ index: { _index: 'movies', _id: 2 } },
{ title: 'The Godfather: Part II', director: 'Francis Ford Coppola', year: 1974 },
],
});

await client.index.refresh({ index: 'movies' });
```

# Multi Search API

The multi-search allows you to execute multiple search requests within a single API call. The following example shows how each search query provides a list of documents from the movie index.

```javascript
try {
const queries = [
{},
{ query: { match: { title: 'The Godfather' } } },
{},
{ query: { match: { title: 'Part II' } } },
];

const multiSearchResponse = await client.msearch({
index: 'movies',
body: queries,
});

multiSearchResponse.body.responses.map((res) =>
res.hits.hits.map((movie) => {
console.log(movie._source);
})
);
} catch (error) {
console.error('An error occurred:', error);
}
```

# Cleanup

```javascript
await client.indices.delete({index: 'movies'});
```
130 changes: 130 additions & 0 deletions samples/msearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
*/
const { Client } = require('@opensearch-project/opensearch');

const client = new Client({
ssl: {
rejectUnauthorized: false,
},
node: 'https://localhost:9200',
auth: {
username: 'admin',
password: 'admin',
},
});

const printResponse = (title, body) => {
console.log(`\n${title}:`);
console.log(body);
};

const handleErrorResponse = (error) => {
if (error.meta && error.meta.body) {
console.error('Error:', error.meta.body.error);
} else {
console.error('Error:', error.message);
}
};

const refreshIndex = async (indexName) => {
try {
const response = await client.indices.refresh({
index: indexName,
});
printResponse(`Refresh response for index ${indexName}`, response.body);
} catch (error) {
handleErrorResponse(error);
}
};

const deleteIndexIfExists = async (indexName) => {
const indexExistsResponse = await client.indices.exists({ index: indexName });
if (indexExistsResponse.statusCode === 200) {
const response = await client.indices.delete({ index: indexName });
printResponse(`Delete existing \`${indexName}\` Index`, response.body);
}
};

const createMoviesIndex = async () => {
const response = await client.indices.create({
index: 'movies',
body: {
mappings: {
properties: {
title: { type: 'text' },
director: { type: 'text' },
year: { type: 'integer' },
},
},
},
});
printResponse('Create `movies` Index', response.body);
};

const addDocumentsToMoviesIndex = async () => {
const response = await client.bulk({
body: [
{ index: { _index: 'movies', _id: 1 } },
{ title: 'The Godfather', director: 'Francis Ford Coppola', year: 1972 },
{ index: { _index: 'movies', _id: 2 } },
{ title: 'The Godfather: Part II', director: 'Francis Ford Coppola', year: 1974 },
],
});
printResponse('Add documents to the `movies` Index using the Bulk API', response.body);
};

const multiSearchExample = async () => {
const queries = [
{},
{
query: { match: { title: 'The Godfather' } },
},
{},
{
query: { match: { title: 'Part II' } },
},
];

const multiSearchResponse = await client.msearch({
index: 'movies',
body: queries,
});

printResponse(
'MultiSearch Response',
multiSearchResponse.body.responses.map((res) => res.hits.hits.map((movie) => movie._source))
);
};

const deleteMoviesIndex = async () => {
const response = await client.indices.delete({ index: 'movies' });
printResponse('Delete `movies` Index', response.body);
};

const start = async () => {
try {
await deleteIndexIfExists('movies');
await createMoviesIndex();
await addDocumentsToMoviesIndex();

// Refresh the 'movies' index
await refreshIndex('movies');

// Multi-search example
await multiSearchExample();

// Delete the 'movies' index
await deleteMoviesIndex();
} catch (error) {
handleErrorResponse(error);
}
};

start();

0 comments on commit 9d3524b

Please sign in to comment.