• Elasticsearch:ES|QL 查询 TypeScript 类型(二)


    在我之前的文章 “Elasticsearch:ES|QL 查询 TypeScript 类型(一)”,我们讲述了如何在 Nodejs 里对 ES|QL 进行查询。在今天的文章中,我们来使用一个完整的例子来进行详细描述。更多有关如何使用 Nodejs 来访问 Elasticsearch的知识,请参阅文章 “Elasticsearch:使用最新的 Nodejs client 8.x 来创建索引并搜索”。

    在一下的演示中,我将使用 Elastic Stack 8.13.4 来进行展示。

    安装

    Elasticsearch 及 Kibana

    如果你还没有安装好自己的 Elasticsearch 及 Kibana,请参考如下的链接来进行安装:

    在安装的时候,我们选择 Elastic Stack 8.x 来进行安装。特别值得指出的是:ES|QL 只在 Elastic Stack 8.11 及以后得版本中才有。你需要下载 Elastic Stack 8.11 及以后得版本来进行安装。

    在首次启动 Elasticsearch 的时候,我们可以看到如下的输出:

    我们需要记下 Elasticsearch 超级用户 elastic 的密码。

    我们还可以在安装 Elasticsearch 目录中找到 Elasticsearch 的访问证书:

    1. $ pwd
    2. /Users/liuxg/elastic/elasticsearch-8.13.4/config/certs
    3. $ ls
    4. http.p12 http_ca.crt transport.p12

    在上面,http_ca.crt 是我们需要用来访问 Elasticsearch 的证书。

    Nodejs 依赖包

    我们可以使用如下的命令来安装最新的 nodejs 客户端包:

    1. yarn add @elastic/elasticsearch
    2. 或者
    3. npm install @elastic/elasticsearch

    我们可以通过如下的命令来查看安装的版本:

    1. $ npm -v @elastic/elasticsearch
    2. 8.19.2

    创建项目目录并拷贝证书

    我们在电脑里创建一个目录,并拷贝相应的 Elasticsearch 访问证书到该目录下:

    1. $ pwd
    2. /Users/liuxg/nodejs/esql
    3. $ cp ~/elastic/elasticsearch-8.13.4/config/certs/http_ca.crt .
    4. $ ls http_ca.crt
    5. http_ca.crt

    我们使用如下的命令来安装:

    npm install --save-dev @types/node

    创建一个叫做 esql.ts 的文件

    touch esql.ts

    我们使用如下的命令来安装 ts-node:

    npm install -g ts-node typescript '@types/node'

    在下面我们将使用如下的命令来运行代码:

    ts-node esql.ts 

    展示

    连接到 Elasticsearch

    我们编辑 esql.ts 如下:

    1. import { Client } from '@elastic/elasticsearch'
    2. import * as fs from "fs";
    3. const client = new Client({
    4. node: 'https://localhost:9200',
    5. auth: {
    6. username: 'elastic',
    7. password: '=VnaMJck+DbYXpHR1Fch'
    8. },
    9. tls: {
    10. ca: fs.readFileSync('./http_ca.crt'),
    11. rejectUnauthorized: false
    12. }
    13. })
    14. client.info()
    15. .then((response) => console.log(JSON.stringify(response)))
    16. .catch((error) => console.error(JSON.stringify(error)));

    在上面,我们使用超级账号 elastic 来进行连接。我们使用证书来访问自签名证书的集群。你需要根据自己的 Elasticsearch 配置修改上面的代码。更多关于如何访问 Elasticsearch 的知识,请阅读文章 “Elasticsearch:使用最新的 Nodejs client 8.x 来创建索引并搜索”。 运行上面的代码,返回:

    1. $ ts-node esql.ts
    2. {"name":"liuxgm.local","cluster_name":"elasticsearch","cluster_uuid":"JXoZ_Xu-QnasteO4AWnVvQ","version":{"number":"8.13.4","build_flavor":"default","build_type":"tar","build_hash":"da95df118650b55a500dcc181889ac35c6d8da7c","build_date":"2024-05-06T22:04:45.107454559Z","build_snapshot":false,"lucene_version":"9.10.0","minimum_wire_compatibility_version":"7.17.0","minimum_index_compatibility_version":"7.0.0"},"tagline":"You Know, for Search"}

    写入数据

    esql.ts

    1. import { Client } from '@elastic/elasticsearch'
    2. import * as fs from "fs";
    3. const client = new Client({
    4. node: 'https://localhost:9200',
    5. auth: {
    6. username: 'elastic',
    7. password: '=VnaMJck+DbYXpHR1Fch'
    8. },
    9. tls: {
    10. ca: fs.readFileSync('./http_ca.crt'),
    11. rejectUnauthorized: false
    12. }
    13. })
    14. client.info()
    15. .then((response) => console.log(JSON.stringify(response)))
    16. .catch((error) => console.error(JSON.stringify(error)));
    17. async function run () {
    18. // Lets index some data into Elasticsearch
    19. await client.indices.exists({
    20. index: "books"
    21. }).then(function (exists) {
    22. if(exists) {
    23. console.log("the index already existed")
    24. } else {
    25. console.log("the index has not been createdyet")
    26. client.helpers.bulk({
    27. datasource: [
    28. { name: "Revelation Space", author: "Alastair Reynolds", release_date: "2000-03-15", page_count: 585 },
    29. { name: "1984", author: "George Orwell", release_date: "1985-06-01", page_count: 328 },
    30. { name: "Fahrenheit 451", author: "Ray Bradbury", release_date: "1953-10-15", page_count: 227 },
    31. { name: "Brave New World", author: "Aldous Huxley", release_date: "1932-06-01", page_count: 268 },
    32. ],
    33. onDocument(_doc) {
    34. return { index: { _index: "books" } }
    35. },
    36. })
    37. }
    38. })
    39. }
    40. run().catch(console.log)

    在运行完上面的代码后,我们可以在 Kibana 中进行查看:

    对数据进行 ES|QL 查询

    1. const response = await client.esql.query({ query: 'FROM books' })
    2. console.log(response)

    完整的代码为:

    esql.ts

    1. import { Client } from '@elastic/elasticsearch'
    2. import * as fs from "fs";
    3. const client = new Client({
    4. node: 'https://localhost:9200',
    5. auth: {
    6. username: 'elastic',
    7. password: '=VnaMJck+DbYXpHR1Fch'
    8. },
    9. tls: {
    10. ca: fs.readFileSync('./http_ca.crt'),
    11. rejectUnauthorized: false
    12. }
    13. })
    14. client.info()
    15. .then((response) => console.log(JSON.stringify(response)))
    16. .catch((error) => console.error(JSON.stringify(error)));
    17. async function run () {
    18. // Lets index some data into Elasticsearch
    19. await client.indices.exists({
    20. index: "books"
    21. }).then(function (exists) {
    22. if(exists) {
    23. console.log("the index already existed")
    24. } else {
    25. console.log("the index has not been createdyet")
    26. client.helpers.bulk({
    27. datasource: [
    28. { name: "Revelation Space", author: "Alastair Reynolds", release_date: "2000-03-15", page_count: 585 },
    29. { name: "1984", author: "George Orwell", release_date: "1985-06-01", page_count: 328 },
    30. { name: "Fahrenheit 451", author: "Ray Bradbury", release_date: "1953-10-15", page_count: 227 },
    31. { name: "Brave New World", author: "Aldous Huxley", release_date: "1932-06-01", page_count: 268 },
    32. ],
    33. onDocument(_doc) {
    34. return { index: { _index: "books" } }
    35. },
    36. })
    37. }
    38. })
    39. const response = await client.esql.query({ query: 'FROM books' })
    40. console.log(response)
    41. }
    42. run().catch(console.log)

    上面代码的完整响应为:

    1. $ ts-node esql.ts
    2. the index already existed
    3. {"name":"liuxgm.local","cluster_name":"elasticsearch","cluster_uuid":"JXoZ_Xu-QnasteO4AWnVvQ","version":{"number":"8.13.4","build_flavor":"default","build_type":"tar","build_hash":"da95df118650b55a500dcc181889ac35c6d8da7c","build_date":"2024-05-06T22:04:45.107454559Z","build_snapshot":false,"lucene_version":"9.10.0","minimum_wire_compatibility_version":"7.17.0","minimum_index_compatibility_version":"7.0.0"},"tagline":"You Know, for Search"}
    4. {
    5. columns: [
    6. { name: 'author', type: 'text' },
    7. { name: 'author.keyword', type: 'keyword' },
    8. { name: 'name', type: 'text' },
    9. { name: 'name.keyword', type: 'keyword' },
    10. { name: 'page_count', type: 'long' },
    11. { name: 'release_date', type: 'date' }
    12. ],
    13. values: [
    14. [
    15. 'Alastair Reynolds',
    16. 'Alastair Reynolds',
    17. 'Revelation Space',
    18. 'Revelation Space',
    19. 585,
    20. '2000-03-15T00:00:00.000Z'
    21. ],
    22. [
    23. 'George Orwell',
    24. 'George Orwell',
    25. '1984',
    26. '1984',
    27. 328,
    28. '1985-06-01T00:00:00.000Z'
    29. ],
    30. [
    31. 'Ray Bradbury',
    32. 'Ray Bradbury',
    33. 'Fahrenheit 451',
    34. 'Fahrenheit 451',
    35. 227,
    36. '1953-10-15T00:00:00.000Z'
    37. ],
    38. [
    39. 'Aldous Huxley',
    40. 'Aldous Huxley',
    41. 'Brave New World',
    42. 'Brave New World',
    43. 268,
    44. '1932-06-01T00:00:00.000Z'
    45. ]
    46. ]
    47. }

    将每行返回为值数组是一个简单的默认设置,在许多情况下很有用。不过,如果你想要一个记录数组(JavaScript 应用程序中的标准结构),则需要额外的努力来转换数据。

    幸运的是,在 8.14.0 中,JavaScript 客户端将包含一个新的 ES|QL 助手来为你执行此操作:

    1. const { records } = await client.helpers.esql({ query: 'FROM books' }).toRecords()
    2. /*
    3. Returns:
    4. [
    5. { name: "Revelation Space", author: "Alastair Reynolds", release_date: "2000-03-15", page_count: 585 },
    6. { name: "1984", author: "George Orwell", release_date: "1985-06-01", page_count: 328 },
    7. { name: "Fahrenheit 451", author: "Ray Bradbury", release_date: "1953-10-15", page_count: 227 },
    8. { name: "Brave New World", author: "Aldous Huxley", release_date: "1932-06-01", page_count: 268 },
    9. ]
    10. */

    截止目前为止,8.14 还没有发布。期待在正式发布后,我们再重新尝试。

    更多关于 ES|QL 的查询,请详细阅读文章 “Elasticsearch:ES|QL 动手实践”。

    在文章的最后,我们可以来完成另外一个查询。我们使用 Kibana 来进行查询:

    1. POST _query?format=txt
    2. {
    3. "query": """
    4. FROM books
    5. | WHERE release_date > "1985-06-01"
    6. | LIMIT 5
    7. """
    8. }

    我们使用 Nodejs 来进行查询:

    1. const query = 'FROM books | WHERE release_date > "1985-06-01" | LIMIT 5'
    2. const response1 = await client.esql.query({ query: query })
    3. console.log(response1)

    esql.ts

    1. import { Client } from '@elastic/elasticsearch'
    2. import * as fs from "fs";
    3. const client = new Client({
    4. node: 'https://localhost:9200',
    5. auth: {
    6. username: 'elastic',
    7. password: '=VnaMJck+DbYXpHR1Fch'
    8. },
    9. tls: {
    10. ca: fs.readFileSync('./http_ca.crt'),
    11. rejectUnauthorized: false
    12. }
    13. })
    14. client.info()
    15. .then((response) => console.log(JSON.stringify(response)))
    16. .catch((error) => console.error(JSON.stringify(error)));
    17. async function run () {
    18. // Lets index some data into Elasticsearch
    19. await client.indices.exists({
    20. index: "books"
    21. }).then(function (exists) {
    22. if(exists) {
    23. console.log("the index already existed")
    24. } else {
    25. console.log("the index has not been createdyet")
    26. client.helpers.bulk({
    27. datasource: [
    28. { name: "Revelation Space", author: "Alastair Reynolds", release_date: "2000-03-15", page_count: 585 },
    29. { name: "1984", author: "George Orwell", release_date: "1985-06-01", page_count: 328 },
    30. { name: "Fahrenheit 451", author: "Ray Bradbury", release_date: "1953-10-15", page_count: 227 },
    31. { name: "Brave New World", author: "Aldous Huxley", release_date: "1932-06-01", page_count: 268 },
    32. ],
    33. onDocument(_doc) {
    34. return { index: { _index: "books" } }
    35. },
    36. })
    37. }
    38. })
    39. const response = await client.esql.query({ query: 'FROM books' })
    40. console.log(response)
    41. const query = 'FROM books | WHERE release_date > "1985-06-01" | LIMIT 5'
    42. const response1 = await client.esql.query({ query: query })
    43. console.log(response1)
    44. }
    45. run().catch(console.log)

    上面最后一个查询的结果为:

  • 相关阅读:
    第3章 docker容器管理
    【计算机网络】 7、websocket 概念、sdk、实现
    音频——解析 PCM 数据
    【Docker】学习笔记
    Android掌控WiFi不完全指南
    画图时使用的函数和一些错误处理
    Cy3.5-PEG-Biotin,Cy3.5-聚乙二醇-生物素,Biotin/mal/dope/dbco-PEG-Cy3.5
    Java线程中interrupt,看一个例子都懂了
    LeetCode HOT 100 —— 4.寻找两个正序数组的中位数
    【linux命令讲解大全】106.使用eject命令退出抽取式设备的方法和选项
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/139470884