如何通过NodeJS调用elasticsearch api?

时间:2018-06-21 16:58:40

标签: node.js amazon-web-services elasticsearch aws-lambda aws-sdk

我的任务是对弹性搜索api进行POST api调用,

https://search-test-search-fqa4l6ubylznt7is4d5yxlmbxy.us-west-2.es.amazonaws.com/klove-ddb/recipe/_search

我以前没有对AWS服务进行api调用的经验。

所以,我尝试了-

axios.post('https://search-test-search-fqa4l6ubylznt7is4d5yxlmbxy.us-west-2.es.amazonaws.com/klove-ddb/recipe/_search')
            .then(res => res.data)
            .then(res => console.log(res));

但是我收到{“ Message”:“用户:匿名用户无权执行:es:ESHttpPost”}

我还签出了一些IAM角色,并将AWSESFullAccess策略添加到我的配置文件中。

仍然无法解决任何问题。

请帮助我。

3 个答案:

答案 0 :(得分:3)

看到错误User: anonymous is not authorized to perform: es:ESHttpPost的原因是因为您在发出请求数据时没有让ElasticSearch知道您是谁-这就是为什么它说“匿名”的原因。

有两种身份验证方式,最简单的方法是使用elasticsearch library。使用此库,您将为IAM角色/用户提供该库一组凭据(访问密钥,秘密密钥)。它将使用它来创建签名的请求。签名的请求将使AWS知道是谁在实际发出请求,因此不会以匿名方式接收,而是您自己。

另一种可行的方法是将访问策略调整为基于IP:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "es:*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "AAA.BBB.CCC.DDD"
                    ]
                }
            },
            "Resource": "YOUR_ELASTICSEARCH_CLUSTER_ARN"
        }
    ]
}

对于您在此处提供ip(范围)的任何人,此特定策略将是开放的。不过,这将省去您必须签署请求的麻烦。

一个有助于通过AWS ES设置elasticsearch-js的库为this one

以下是一个工作示例:

const AWS = require('aws-sdk')
const elasticsearch = require('elasticsearch')
const awsHttpClient = require('http-aws-es')

let client = elasticsearch.Client({
    host: '<YOUR_ES_CLUSTER_ID>.<YOUR_ES_REGION>.es.amazonaws.com',
    connectionClass: awsHttpClient,
    amazonES: {
        region: '<YOUR_ES_REGION>',
        credentials: new AWS.Credentials('<YOUR_ACCESS_KEY>', '<YOUR_SECRET_KEY>')
    }
});

client.search({
    index: 'twitter',
    type: 'tweets',
    body: {
        query: {
            match: {
                body: 'elasticsearch'
            }
        }
    }
})
.then(res => console.log(res));

答案 1 :(得分:0)

Elasticsearch npm软件包即将被弃用,请使用@ elastic / elasticsearch和@ acuris / aws-es-connection,因此您不必为该功能提供IAM Credentails。

代码在这里,我用:

'use strict';

const { Client } = require('@elastic/elasticsearch');
const { createAWSConnection, awsGetCredentials } = require('@acuris/aws-es- 
connection');

module.exports.get_es_interests = async event => {
const awsCredentials = await awsGetCredentials();
const AWSConnection = createAWSConnection(awsCredentials);
const client = new Client({
...AWSConnection,
node: 'your-endpoint',
});

let bodyObj = {};
try {
    bodyObj = JSON.parse(event.body);
} catch (jsonError) {
    console.log('There was an error parsing the JSON Object', jsonError);
    return {
        statusCode: 400
    };
}

let keyword = bodyObj.keyword;

const { body } = await client.search({
index: 'index-name',
body: {
  query: {
    match: {
      name: {
        query: keyword,
        analyzer: "standard"
      }
    }
  }
}
});

var result = body.hits.hits;

return result;
};

答案 2 :(得分:0)

现在有https://github.com/gosquared/aws-elasticsearch-js

导入

const AWS = require('aws-sdk');
const ElasticSearch = require('@elastic/elasticsearch');
const { createConnector } = require('aws-elasticsearch-js');

使用可在 ~/.aws/config 上找到的命名配置文件配置客户端。您可以通过执行以下操作来验证这一点:cat ~/.aws/config 应该输出如下内容:

[profile work]
region=ap-southeast-2

[default]
region = ap-southeast-1
const esClient = new ElasticSearch.Client({
  nodes: [
    '<aws elastic search domain here>'
  ],
  Connection: createConnector({
    region: '<region>',
    getCreds: callback =>
      callback(
        null,
        new AWS.SharedIniFileCredentials({ profile: '<target profile>' })
      )
  })
});

然后你就可以开始使用它了:

// this query will delete all documents in an index
await esClient.delete_by_query({
  index: '<your index here>',
  body: {
    query: {
      match_all: {}
    }
  }
});

参考文献: