【问题标题】:Sending requests to Elasticsearch with axios使用 axios 向 Elasticsearch 发送请求
【发布时间】:2023-03-31 22:46:01
【问题描述】:

我正在开发一个需要从 elsaticsearch 获取数据的反应应用程序。 在前端,实际上我正在尝试使用 axios 来执行请求:

const query = {
  query: {
    match: {
      "_id": "AV12n5KzsohD5gXzTnOr"
    }
  }
};

axios.get('http://localhost:9200/my-index/my-type/_search', query)
  .then((res) => {
    console.log(res);
  });

我想获取带有某个 ID 的特定文档。上面的查询实际上在 kibana 中有效。但是,上面的查询返回了my-type里面的所有文档,我这里做错了什么?

【问题讨论】:

  • 抱歉我更新了帖子,谢谢。

标签: reactjs elasticsearch axios


【解决方案1】:

我认为以下应该可行。尽管Axios README 表示data 仅适用于PUTPOSTPATCH 请求,但我在代码中没有看到任何强制执行此操作的内容,简化的测试表明请求正文确实是针对GET 请求发送的:

axios.get('http://localhost:9200/my-index/my-type/_search', {
  data: JSON.stringify(query),
}).then((res) => {
  console.log(res);
});

编辑

请注意,我只在 Node.js 中测试过这个,而不是在浏览器中。浏览器可能不太倾向于将请求正文包含在 GET 请求中。

编辑 2

Elasticsearch 似乎允许 sending the request body in a parameter instead,可能是因为这个问题。

这应该可以解决问题:

axios.get('http://localhost:9200/my-index/my-type/_search', {
  params: {
    source: JSON.stringify(query),
    source_content_type: 'application/json'
  }
}).then((res) => {
  console.log(res);
});

编辑 3

这确实似乎是在浏览器中发出GET 请求的一般限制。每the documentation for XMLHttpRequest.send

如果请求方法是 GET 或 HEAD,则忽略参数并将请求正文设置为 null。

【讨论】:

  • 谢谢!我完全按照您的方式进行了尝试,但仍然得到了所有文件,而不是我想要的文件。我认为我的 get-request 没有向 elasticsearch 发送任何有效负载,很奇怪......
  • 嗨 smarx,您的第二次编辑确实有效!嗯.. 我猜 axios 是那种不接受非 POST 请求的请求正文的库。无论如何,谢谢你的帮助:)
  • 我怀疑 Axios 可以很好地处理它(就像在 Node.js 中一样),但浏览器不能。
  • 据我所知,axios 在浏览器/节点中的工作方式似乎非常不同。在浏览器中,它必须使用 XMLHttprequest 作为 http 适配器。看到这个:github.com/mzabriskie/axios/issues/456
  • 是的,我怀疑是浏览器限制(即 XHR)阻止了请求正文的发送。
【解决方案2】:

只需使用.post()

来自 Elasticsearch docs

HTTP GET 和 HTTP POST 都可以用于执行带有正文的搜索。由于并非所有客户端都支持带有正文的 GET,因此也允许使用 POST

【讨论】:

    【解决方案3】:

    试试这个

    axios.get(`http://localhost:9200/my-index/my-type/_search?q=${_id:AV12n5KzsohD5gXzTnOr}`)
      .then((res) => {
        console.log(res);
    });
    

    【讨论】:

    • 是的,这会起作用。但是对于更复杂的 DSL 查询,我认为 smarx 的第二次编辑应该是最好的解决方案。谢谢!
    【解决方案4】:

    如果他们来这里,只是为了其他人。以下方式对我有用:(不要关注样本数据)

    axios({
        url: 'your ES url',
        method: 'POST',
        timeout: 0,
        headers: {
          'Content-Type': 'application/json'
        },
        data: JSON.stringify({
          query: {
            bool: {
              filter: [
                { match_all: {} },
                { match_phrase: { 'data.gateway': { query: 'gateway1' } } },
                { match_phrase: { 'data.sensor': { query: '10001' } } },
                { range: { 'data.dateTime': { lte: '2020-05-26 20:25:00' } } },
                {
                  range: {
                    receivedInES: {
                      format: 'strict_date_optional_time',
                      gte: '2020-05-25T19:37:23.621Z',
                      lte: '2020-05-26T19:37:23.621Z'
                    }
                  }
                }
              ]
            }
          }
        })
      })
    

    【讨论】:

      猜你喜欢
      • 2019-09-27
      • 2021-10-30
      • 2020-03-28
      • 1970-01-01
      • 2019-04-26
      • 2018-07-11
      • 2022-01-18
      • 2019-12-18
      • 2022-01-15
      相关资源
      最近更新 更多