[英]How to connect to AWS Elasticsearch using the Elasticsearch JavaScript SDK?
我正在使用AWS Elasticsearch服務並希望通過elasticsearch.js進行連接,但需要一個端口。
看起來 AWS 只提供REST API (例如通過 curl),在端口 80 上運行。我的集群已啟動,我可以通過瀏覽器訪問,但不能通過 elasticsearch.js。
這個例子對我不起作用:
var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
host: 'localhost:9200', // not working: '', 80, default: 443
log: 'trace'
});
client.ping({
requestTimeout: 1000
}, function (error) {
if (error) {
console.trace('elasticsearch cluster is down!');
} else {
console.log('All is well');
}
});
我找到了http-aws-es ,但它也不起作用。
有什么想法嗎? 提前致謝!
對於elasticsearch.client,您可以將http-aws-es 用於connectionClass 和帶有密鑰的amazonES。
var client = new elasticsearch.Client({
hosts: config.elasticsearch.host,
connectionClass: require('http-aws-es'),
amazonES: {
region: config.aws.region,
accessKey: config.aws.key,
secretKey: config.aws.secret
}
});
NPM 包elasticsearch
已棄用,取而代之的是@elastic/elasticsearch
因此,而不是使用http-aws-es
,這是應該的工作使用舊版elasticsearch
包,您可以考慮使用包@ acuris / AWS-ES-連接,為新elasticsearch客戶的AWS ES連接@elastic/elasticsearch
。 它在我的項目中對我很有效。 你可以在它的自述文件中找到它的用法,但這里有一段示例代碼:
import {
createAWSConnection,
awsGetCredentials,
} from '@acuris/aws-es-connection';
import { Client } from '@elastic/elasticsearch';
export const getESClient = async () => {
const esEndpoint = process.env.AWS_ES_ENDPOINT;
if (!esEndpoint) {
throw new Error(
'AWS_ES_ENDPOINT ENV not set.'
);
}
const awsCredentials = await awsGetCredentials();
const AWSConnection = createAWSConnection(awsCredentials);
const client = new Client({
...AWSConnection,
node: esEndpoint,
});
return client;
};
export const createNewIndex = async (index: string) => {
try {
const client = await getESClient();
const exists = await client.indices.exists({ index });
if (!exists || !exists.statusCode || exists.statusCode !== 404) {
console.log(`Index ${index} might alrady exist.`, exists);
return false;
}
const created = await client.indices.create({
index,
body: {
mappings: {
properties: {
product_id: {
type: 'keyword',
},
product_description: {
type: 'text',
},
},
},
},
});
console.log(`Index created for ${index}`, created);
} catch (error) {
console.log(`Error creating index ${index}`, error);
return false;
}
return true;
};
這是我在 TypeScript 中使用的Connection
類的一個實現:
import { Connection as UnsignedConnection } from '@elastic/elasticsearch';
import * as AWS from 'aws-sdk';
import RequestSigner from 'aws-sdk/lib/signers/v4';
import { ClientRequest, IncomingMessage } from 'http';
class AwsElasticsearchError extends Error {}
type RequestOptions = Parameters<UnsignedConnection['request']>[0];
class AwsSignedConnection extends UnsignedConnection {
public request(
params: RequestOptions,
callback: (err: Error | null, response: IncomingMessage | null) => void,
): ClientRequest {
const signedParams = this.signParams(params);
return super.request(signedParams, callback);
}
private signParams(params: RequestOptions): RequestOptions {
const region = AWS.config.region || process.env.AWS_DEFAULT_REGION;
if (!region) throw new AwsElasticsearchError('missing region configuration');
if (!params.method) throw new AwsElasticsearchError('missing request method');
if (!params.path) throw new AwsElasticsearchError('missing request path');
if (!params.headers) throw new AwsElasticsearchError('missing request headers');
const endpoint = new AWS.Endpoint(this.url.href);
const request = new AWS.HttpRequest(endpoint, region);
request.method = params.method;
request.path = params.querystring
? `${params.path}/?${params.querystring}`
: params.path;
request.body = params.body;
Object.entries(params.headers).forEach(([header, value]) => {
if (value === undefined) return;
if (typeof value === 'string') request.headers[header] = value;
else if (typeof value === 'number') request.headers[header] = `${value}`;
else request.headers[header] = value.join('; ');
});
request.headers.Host = endpoint.host;
const signer = new RequestSigner(request, 'es');
signer.addAuthorization(AWS.config.credentials, new Date());
return request;
}
}
export { AwsSignedConnection, UnsignedConnection, AwsElasticsearchError };
然后您可以僅在憑據可用時提供它,因此您可以使用它來指向本地(例如 Docker)Elasticsearch,而無需憑據:
import awsSdk from 'aws-sdk';
import elasticsearch from '@elastic/elasticsearch';
import { AwsSignedConnection, UnsignedConnection } from '../aws-es-connector';
client = new elasticsearch.Client({
Connection: awsSdk.config.credentials ? AwsSignedConnection : UnsignedConnection,
node: elasticsearchEndpoint,
});
我花了一個小時找到適合我的方法。 唯一有效的是:
var elasticsearch = require('elasticsearch');
var AWS = require('aws-sdk');
var connectionClass = require('http-aws-es');
AWS.config.update({
credentials: new AWS.Credentials('accessKey','secret'),
region: 'us-east-1'
});
var client = new elasticsearch.Client({
host: 'https://yourdomainurl.us-east-1.es.amazonaws.com',
log: 'debug',
connectionClass: connectionClass,
amazonES: {
credentials: new AWS.EnvironmentCredentials('AWS')
}
});
確保您為 IAM 用戶添加了訪問策略。 那么一切都應該正常工作。 希望這會幫助某人。
Elasticsearch Service 端點在 HTTPS(端口 443)或 HTTP(端口 80)上運行。
您可以將您的 localhost:9200 交換到此以進行簡單的交換替換
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.