# @elastic/app-search-node 中文文档

规范地址：https://npmcn.com/package/%40elastic/app-search-node/

版本：8\.3\.2
npm 元数据更新时间：2026-09-25T13:38:04.446Z
中文译文更新时间：2026-11-13T10:45:01.730Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40elastic/app-search-node
原文对照：https://npmcn.com/package/%40elastic/app-search-node/?lang=original
项目主页：https://github.com/elastic/app-search-node#readme
源码仓库：https://github.com/elastic/app-search-node

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：42.8 kB，6 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- Node.js 要求：\>= v6\.5\.0
- 运行依赖：2 个
- 首次发布：2019-07-29T18:22:10.195Z
- 最新版本发布：2022-07-08T19:03:24.226Z
- 近 30 天下载量：22952（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：31（近 12 个月 0 个）

## 中文简介

弹性 App 搜索节点.js 客户端

## 安装

```sh
npm install @elastic/app-search-node
```

也可以使用：`pnpm add @elastic/app-search-node`、`yarn add @elastic/app-search-node`、`bun add @elastic/app-search-node`

## README

> **此客户端已贬值**
> 
> 企业搜索版8.3.2,我们正引导用户到新的 [企业搜索节点客户端](https://github.com/elastic/enterprise-search-js) 财务报告和审定财务报表 贬取此客户端.
> 
> 这个项目的开发工作将仅限于修复错误. 今后所有的增强都将以企业搜索节点客户端为重点.
> 
> 谢谢! - 有弹性

![Elastic App Search Logo](https://github.com/elastic/app-search-node/blob/master/logo-app-search.png?raw=true)

[![CircleCI build](https://circleci.com/gh/elastic/app-search-node.svg?style=svg)](https://circleci.com/gh/elastic/app-search-node)

> 用于构建优秀相关搜索经验的首发方Node.JS客户端 [弹性 App 搜索](https://www.elastic.co/products/app-search)。 。 。 .

## 目录

-   [开始](https://npmcn.com/package/%40elastic/app-search-node/#readme-getting-started-)
-   [版本](https://npmcn.com/package/%40elastic/app-search-node/#readme-versioning)
-   [使用量](https://npmcn.com/package/%40elastic/app-search-node/#readme-usage)
-   [正在测试](https://npmcn.com/package/%40elastic/app-search-node/#readme-running-tests)
-   [财务问题](https://npmcn.com/package/%40elastic/app-search-node/#readme-faq-)
-   [贡献](https://npmcn.com/package/%40elastic/app-search-node/#readme-contribute-)
-   [许可证](https://npmcn.com/package/%40elastic/app-search-node/#readme-license-)

* * *

## 开始 QQ

要安装此软件包, 请运行 :

```bash
npm install @elastic/app-search-node
```

## 版本

这个客户端在App Search同时被版本并发布.

为保证相容性,在相应的App Search执行的主要版本中使用此库的最新版本.

例如, App 搜索 `7.3`,使用时 `7.3` 本图书馆或以上,但不是 `8.0`。 。 。 .

如果你正在使用 [SaaS 版本可在sourkype.com上查阅](https://app.swiftype.com/as) app Search中,您应当使用客户端的7.5.x版本.

## 使用量

### 设置: 配置客户端和认证

使用此客户端假设您已有实例 [弹性 App 搜索](https://www.elastic.co/products/app-search) 继续跑.

客户端使用 `baseUrlFn` 财务报告和审定财务报表 `apiKey` 参数.

```javascript
const apiKey = 'private-mu75psc5egt9ppzuycnc2mc3'
const baseUrlFn = () => 'http://localhost:3002/api/as/v1/'
const client = new AppSearchClient(undefined, apiKey, baseUrlFn)
```

说明:

这个 `[apiKey]` 认证请求到 API . 您可以与客户端使用任意密钥类型, 但每个类型都有不同的范围 . 关于密钥的更多信息,请查看 [文档](https://swiftype.com/documentation/app-search/api/credentials)。 。 。 .

#### Swiftype.com App搜索用户 :

使用时 [SaaS 版本可在sourkype.com上查阅](https://app.swiftype.com/as) 在 App 搜索中,您可以使用您的 `hostIdentifier` 代替 `baseUrlFn` 参数. 这个 `hostIdentifier` 可在 [全权证书](https://app.swiftype.com/as#/credentials) 菜单.

```javascript
const AppSearchClient = require('@elastic/app-search-node')
const hostIdentifier = 'host-c5s2mj'
const apiKey = 'private-mu75psc5egt9ppzuycnc2mc3'
const client = new AppSearchClient(hostIdentifier, apiKey)
```

### API 方法

##### 索引:创建或替换文档

```javascript
const engineName = 'favorite-videos'
const documents = [
  {
    id: 'INscMGmhmX4',
    url: 'https://www.youtube.com/watch?v=INscMGmhmX4',
    title: 'The Original Grumpy Cat',
    body: 'A wonderful video of a magnificent cat.'
  },
  {
    id: 'JNDFojsd02',
    url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
    title: 'Another Grumpy Cat',
    body: 'A great video of another cool cat.'
  }
]

client
  .indexDocuments(engineName, documents)
  .then(response => console.log(response))
  .catch(error => console.log(error))
```

注意此 API 将不会丢入索引错误 。 每个文档的响应正文中包含错误:

```json
[
  { "id": "park_rocky-mountain", "errors": [] },
  {
    "id": "park_saguaro",
    "errors": ["Invalid field value: Value 'foo' cannot be parsed as a float"]
  }
]

```

##### 索引:更新文档(部分更新)

```javascript
const engineName = 'favorite-videos'
const documents = [
  {
    id: 'INscMGmhmX4',
    title: 'Updated title'
  }
]

client
  .updateDocuments(engineName, documents)
  .then(response => console.log(response))
  .catch(error => console.log(error))
```

##### 获取文档

```javascript
const engineName = 'favorite-videos'
const documentIds = ['INscMGmhmX4', 'JNDFojsd02']

client
  .getDocuments(engineName, documentIds)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 列出文档

```javascript
const engineName = 'favorite-videos'

// Without paging
client
  .listDocuments(engineName)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))

// With paging
client
  .listDocuments(engineName, { page: { size: 10, current: 1 } })
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 销毁文档

```javascript
const engineName = 'favorite-videos'
const documentIds = ['INscMGmhmX4', 'JNDFojsd02']

client
  .destroyDocuments(engineName, documentIds)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 列出引擎

```javascript
client
  .listEngines({ page: { size: 10, current: 1 } })
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 获取引擎

```javascript
const engineName = 'favorite-videos'

client
  .getEngine(engineName)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 创建引擎

```javascript
const engineName = 'favorite-videos'

client
  .createEngine(engineName, { language: 'en' })
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 正在摧毁引擎

```javascript
const engineName = 'favorite-videos'

client
  .destroyEngine(engineName)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 搜索中

```javascript
const engineName = 'favorite-videos'
const query = 'cat'
const searchFields = { title: {} }
const resultFields = { title: { raw: {} } }
const options = { search_fields: searchFields, result_fields: resultFields }

client
  .search(engineName, query, options)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 多搜索器

```javascript
const engineName = 'favorite-videos'
const searches = [
  { query: 'cat', options: {
      search_fields: { title: {} },
      result_fields: { title: { raw: {} } }
  } },
  { query: 'grumpy', options: {} }
]

client
  .multiSearch(engineName, searches)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 查询建议

```javascript
const engineName = 'favorite-videos'
const options = {
  size: 3,
  types: {
    documents: {
      fields: ['title']
    }
  }
}

client
  .querySuggestion(engineName, 'cat', options)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 列出限制

```javascript
const engineName = 'favorite-videos'

client
  .listCurations(engineName)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))

// Pagination details are optional
const paginationDetails = {
        page: {
          current: 2,
          size: 10
        }
      }

client
  .listCurations(engineName, paginationDetails)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 获取校正

```javascript
const engineName = 'favorite-videos'
const curationId = 'cur-7438290'

client
  .getCuration(engineName, curationId)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 创建曲线

```javascript
const engineName = 'favorite-videos'
const newCuration = {
  queries: ['cat blop'],
  promoted: ['Jdas78932'],
  hidden: ['INscMGmhmX4', 'JNDFojsd02']
}

client
  .createCuration(engineName, newCuration)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 更新曲线

```javascript
const engineName = 'favorite-videos'
const curationId = 'cur-7438290'
// "queries" is required, either "promoted" or "hidden" is required.
// Values sent for all fields will overwrite existing values.
const newDetails = {
  queries: ['cat blop'],
  promoted: ['Jdas78932', 'JFayf782']
}

client
  .updateCuration(engineName, curationId, newDetails)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 删除限制

```javascript
const engineName = 'favorite-videos'
const curationId = 'cur-7438290'

client
  .destroyCuration(engineName, curationId)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 获取Schemas

```javascript
const engineName = 'favorite-videos'

client
  .getSchema(engineName)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 更新 Schemas

```javascript
const engineName = 'favorite-videos'
const schema = {
  views: 'number',
  created_at: 'date'
}

client
  .updateSchema(engineName, schema)
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 创建已签名的搜索密钥

创建只返回标题字段的搜索密钥 .

```javascript
const publicSearchKey = 'search-xxxxxxxxxxxxxxxxxxxxxxxx'
// This name must match the name of the key above from your App Search dashboard
const publicSearchKeyName = 'search-key'
const enforcedOptions = {
  result_fields: { title: { raw: {} } },
  filters: { world_heritage_site: 'true' }
}

// Optional. See https://github.com/auth0/node-jsonwebtoken#usage for all options
const signOptions = {
  expiresIn: '5 minutes'
}

const signedSearchKey = AppSearchClient.createSignedSearchKey(
  publicSearchKey,
  publicSearchKeyName,
  enforcedOptions,
  signOptions
)

const baseUrlFn = () => 'http://localhost:3002/api/as/v1/'
const client = new AppSearchClient(undefined, signedSearchKey, baseUrlFn)

client.search('sample-engine', 'everglade')
```

##### 创建元引擎

```javascript
const engineName = 'my-meta-engine'

client
  .createMetaEngine(engineName, ['source-engine-1', 'source-engine-2'])
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 在元引擎中添加源引擎

```javascript
const engineName = 'my-meta-engine'

client
  .addMetaEngineSources(engineName, ['source-engine-3'])
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 从元引擎中删除源引擎

```javascript
const engineName = 'my-meta-engine'

client
  .deleteMetaEngineSources(engineName, ['source-engine-3'])
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

##### 创建引擎

```javascript
const engineName = 'my-meta-engine'

client
  .createEngine(engineName, {
    type: 'meta',
    source_engines: ['source-engine-1', 'source-engine-2']
  })
  .then(response => console.log(response))
  .catch(error => console.log(error.errorMessages))
```

### 对于此客户端中没有的 App 搜索 API

我们试图让这个客户端随时更新App Search中所有可用的API端点.

还有一些API可能还没有提供. 对于这些API,请使用低等客户端连接到任何App Search端点.

```javascript
const engineName = 'favorite-videos'
const options = {
  query: 'cats'
}

const Client = require('@elastic/app-search-node/lib/client')
const client = new Client('private-mu75psc5egt9ppzuycnc2mc3', 'http://localhost:3002/api/as/v1/')
client.post(`engines/${encodeURIComponent(engineName)}/search`, options).then(console.log)
```

## 正在测试

```bash
npm test
```

此工程的规格 [节点重放](https://github.com/assaf/node-replay) 获取固定装置.

应该从正在运行的 App Search 实例中捕获新的固定装置.

为了捕捉出新的固定装置,运行如下命令:

```
nvm use
HOST_IDENTIFIER=host-c5s2mj API_KEY=private-b94wtaoaym2ovdk5dohj3hrz REPLAY=record npm run test -- -g 'should create a meta engine'
```

要打破这一点一点点...

-   `HOST_IDENTIFIER` - 使用此选项来覆盖测试中使用的假值, 并带有实际有效的值, 用于您的 App 搜索实例以记录来自
-   `API_KEY` - 使用此选项来覆盖测试中使用的假值, 并带有实际有效的值, 用于您的 App 搜索实例以记录来自
-   `REPLAY=record` - 告诉重播,如果一个新的回应不存在的话
-   `npm run test` - 进行测试
-   `-- -g 'should create a meta engine'` - 将测试限制在只运行您创建的新测试, 例如“ 应创建元引擎 ”

这将创建一个新的固定符, 确保您手动编辑该固定符以替换主机标识符和 api 密钥 记录在测试所用的值上.

您还需要确保固定在正确命名的目录中 `fixtures` 根据被使用的主机.

你会知道,如果有什么不对 因为这样会出错 当你运行 `npm run test` 错误如:

```
Error: POST https://host-c5s2mj.api.swiftype.com:443/api/as/v1/engines refused: not recording and no network access
```

## 问 题

### 我在哪里报告与客户的问题?

如果有东西不起作用,请打开 [问题](https://github.com/elastic/app-search-node/issues/new)。 。 。 .

### 哪里可以多学点App Search?

你最好的赌注是读 [文档](https://swiftype.com/documentation/app-search)。 。 。 .

### 我还能去哪找人帮忙?

你可以去检查 [弹性 App 搜索社区讨论论坛](https://discuss.elastic.co/c/app-search)。 。 。 .

## 贡献

我们欢迎该项目的捐助者。 在你开始前, 几个笔记...

-   在启动拉动请求前,请创建一个问题 [讨论您提案的范围](https://github.com/elastic/app-search-node/issues)。 。 。 .
-   请酌情写出简单的代码和简明文档.

## 许可证 QQ

[Apache 2.0 (英语)](https://github.com/elastic/app-search-node/blob/master/LICENSE.txt) © [弹性](https://github.com/elastic)

谢谢大家 [捐助者](https://github.com/elastic/app-search-node/graphs/contributors)来啊!

## 常见问题

### @elastic/app-search-node 是什么？

弹性 App 搜索节点\.js 客户端

### 如何安装 @elastic/app-search-node？

在项目目录运行 npm install @elastic/app-search-node，或使用 pnpm add / yarn add / bun add。

### @elastic/app-search-node 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/elastic\_\_app-search-node 是否存在。

### @elastic/app-search-node 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @elastic/app-search-node 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>= v6\.5\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @elastic/app-search-node 可以商用吗？

@elastic/app-search-node 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @elastic/app-search-node 的下载量有多少？

根据 npm 官方下载统计，@elastic/app-search-node 在 2026/10/13 – 2026/11/11 这 30 天内被下载 22,952 次，日均约 765 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @elastic/app-search-node 还在维护吗？

最新版本 8\.3\.2 发布于 2022/07/09（4 年前）；至今共发布 31 个版本，其中过去 12 个月发布了 0 个；首次发布于 2019/07/30。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

