Elasticsearch/OpenSearch可以说是企业级搜索应用的最佳选择。相较于传统的关系型数据库,Elasticsearch/OpenSearch更适合于存储海量数据并对其进行全文检索和数据分析(聚合)。下面介绍如何在Node.js中使用AWS OpenSearch。

Elasticsearch教程
Elasticsearch系列教程
- Elasticsearch教程之一:介绍
- Elasticsearch教程之二:索引,分词及映射
- Elasticsearch教程之三:API
- Elasticsearch教程之四:AWS OpenSearch
- Elasticsearch教程之五:AWS OpenSearch Node.js客户端的使用
- Elasticsearch教程之六:Python客户端的使用
- Elasticsearch教程之七:在OpenSearch中使用聚合实现Facet
安装
bash
npm install @opensearch-project/opensearch
npm install dotenv
关于如何使用Node.js调用OpenSearch API,请参考官网文档。下面介绍总结一个常用的功能。例子基本上都是在官网示例的基础上修改的。
创建索引
Javascript
const { Client } = require("@opensearch-project/opensearch");
let client = new Client({
node: 'https://xxxxxx.eu-west-1.es.amazonaws.com'
});
const test_create_index = async () => {
let settings = {
settings: {
index: {
number_of_shards: 1,
number_of_replicas: 1,
},
},
};
let response = await client.indices.create({
index: "demoindex",
body: settings,
});
console.log("Creating index:");
console.log(response.body);
}
test_create_index();
获取索引列表
JavaScript
async getIndices() {
return client.cat.indices({ format: 'json' });
},
只有当索引不存在时创建
JavaScript
async createIndexIfNotExist(indexName: string, settings: any) {
const indices = (await this.getIndices()).body;
if (indices) {
for (let i = 0; i < indices.length; i += 1) {
if (indices[i].index === indexName) {
return indices[i];
}
}
}
return this.createIndex(indexName, settings);
},
async createIndex(indexName: string, settings: any) {
const response = await client.indices.create({
index: indexName,
body: settings,
});
return response.body;
},
更新mapping
JavaScript
async updateMappings(indexName: string, mappings: any) {
await client.indices.putMapping({
index: indexName,
body: mappings,
});
},
传递过来的mapping类似于:
JavaScript
{
"properties": {
"author": {
"type": "keyword"
},
"address": {
"type": "text"
},
}
}
添加文档
JavaScript
async addDoc(indexName: string, id: string, doc: any) {
const response = await client.index({
id,
index: indexName,
body: doc,
refresh: true,
});
return response.body;
},
删除索引/文档
删除索引
Javascript
let response = await client.indices.delete({
index: index_name,
});
删除文档
Javascript
let response = await client.delete({
index: index_name,
id: id,
});
查询
基本查询
Javascript
const { Client } = require("@opensearch-project/opensearch");
let client = new Client({
node: 'https://xxxxxx.eu-west-1.es.amazonaws.com'
});
const test_search = async () => {
let query = {
query: {
match: {
name: {
query: "Harry",
},
},
},
};
let response = await client.search({
index: "demoindex",
body: query,
});
console.log("Searching:");
console.log(response.body);
}
test_search();
使用slop
Query可以使用OS中的各种关键字,比如:
JavaScript
let query = {
query: {
match: {
name: {
query: "food with cheese",
slop: 10
},
},
},
}
按照关键字查找
JavaScript
let query = {
query: {
match: {
name: {
query: "+(dessert | cake) -onion (cherry | stawberry)",
default_field: "desc",
},
},
},
}
进行term查询
JavaScript
query: {
term: {
age: 25
}
}
JavaScript
query: {
range: {
age: {
gte: 20,
lte: 30
}
}
}
组合查询
JavaScript
query: {
bool: {
filter: [{range: {age: {ate: 18}}}],
must: [{match_phrasae: {categories: 'Math'}}],
should: [{match: {title: 'undergrade'}}],
must_not: [{match: {content: 'gcse'}}],
}
}
返回文档
返回文档的格式是这样的:
Javascript
[
{
_index: 'demoindex',
_type: '_doc',
_id: '101',
_score: 0.2876821,
_source: { name: 'Harry Potter', age: '12', school: 'Hogwarts' }
}
]
Aggregation聚合
Javascript
const { Client } = require("@opensearch-project/opensearch");
let client = new Client({
node: 'https://xxxxxx.eu-west-1.es.amazonaws.com'
});
const test_aggs = async () => {
let query = {
query: {
aggs: {
demo: {
avg: { // avg, min, max, stats
field: "age"
}
}
}
},
};
let response = await client.search({
index: "demoindex",
body: query,
});
console.log("Searching:");
console.log(response.body);
}
test_search();
或者:
JavaScript
aggs: {
demo: {
histogram: {
field: "age",
interval: 1
}
}
}