Elasticsearch 是一个基于 Lucene 的开源搜索引擎。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 具有高弹性,支持即时和实时的复杂搜索功能。NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架,它使用 TypeScript 开发并且结合了 OOP(面向对象编程)、FP(函数式编程)和 FRP(函数响应式编程)。
整合 Elasticsearch 和 NestJS 可以为我们提供一种十分强大的搜索解决方案,我们可以用这个组合来建立获取及解析数据的高效应用。
首先,我们需要使用 NestJS CLI 工具创建一个新的 NestJS 项目。在你的命令行中输入以下命令:
shellshell复制代码 nest new nest-elasticsearch-project
在创建好 NestJS 项目后,我们要安装 Elasticsearch 模块。打开命令行,进入项目文件夹,然后输入以下命令:
shellnpm install --save @nestjs/elasticsearch @elastic/elasticsearch
这里,@nestjs/elasticsearch
是 NestJS 的 Elasticsearch 模块,@elastic/elasticsearch
是 ElasticSearch 提供的 Node.js 客户端。
接着,我们需要在根模块 (app.module.ts
) 中导入并配置 ElasticSearch Module
。这个模块将允许我们在整个项目中使用 ElasticSearch。
typescript// app.module.ts import { Module } from '@nestjs/common'; import { ElasticsearchModule } from '@nestjs/elasticsearch'; @Module({ imports: [ ElasticsearchModule.register({ node: 'http://localhost:9200', }), ], }) export class AppModule { }
在这个例子中,我们假设 ElasticSearch 在本地的 9200 端口运行。如果你的 ElasticSearch 实例运行在其他地方,根据你的实际情况修改 node
的配置。
现在我们可以创建一个服务来使用 ElasticSearch 了。在这个服务中,我们可以注入 ElasticsearchService
来调用 ElasticSearch 的 API。
shellnest generate service search
在生成的 search.service.ts
中,我们可以编写以下代码:
typescript// search.service.ts import { Injectable } from '@nestjs/common'; import { ElasticsearchService } from '@nestjs/elasticsearch'; @Injectable() export class SearchService { constructor(private readonly elasticsearchService: ElasticsearchService) { } async search(query: string) { const { body } = await this.elasticsearchService.search({ index: 'your_index', body: { query: { match: { title: query }, }, }, }); return body.hits.hits.map(hit => hit._source); } }
上面的步骤中创建了一个 search
方法,这个方法会在指定的索引中搜索匹配查询的文档。
ElasticSearch 的优势就是支持数据的模糊搜索,然后系统数据一般会存在MySQL这种持久性数据库。为了能够实现数据的模糊搜索,我们需要将MySQL的关键数据同步到 ElasticSearch,然后利用 ElasticSearch 的模糊搜索能力实现高级搜索功能。
接下来介绍整个流程的实现步骤:
可以基于 typeorm
实现对MySQL数据的操作,但是不是本文的重点,可以参考我之前写的 NestJS集成 TypeORM 的教程https://www.levenx.com/article/how-to-implement-curd-restful-api-interface-using-nestjs-and-typeorm
使用 TypeORM 从 MySQL 数据库中获取数据,并使用 Elasticsearch 的 Node.js 客户端在 Elasticsearch 中索引这些数据。
typescript// search.service.ts import { Injectable } from '@nestjs/common'; import { ElasticsearchService } from '@nestjs/elasticsearch'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Article } from './article.entity'; @Injectable() export class SearchService { constructor( private readonly elasticsearchService: ElasticsearchService, @InjectRepository(Article) private readonly articleRepo: Repository<Article>, ) { } async **indexArticles**() { const articles = await this.articleRepo.find(); articles.forEach(async article => { await this.elasticsearchService.index({ index: 'articles', id: String(article.id), body: article, }); }); } }
typescriptasync search(query: string) { const { body } = await this.elasticsearchService.search({ index: 'articles', body: { query: { multi_match: { query, fields: ['title', 'content'], }, }, }, }); return body.hits.hits.map(hit => hit._source); }
typescriptasync search(query: string) { const { body } = await this.elasticsearchService.search({ index: 'articles', body: { query: { fuzzy: { title: { value: query, }, }, }, }, }); return body.hits.hits.map(hit => hit._source); }
Elasticsearch 是一个强大的搜索和分析引擎,而 NestJS 则是一个能够帮助我们创建可维护、可测试和可扩展的 Node.js 服务端应用的框架。将它们结合在一起,可以让我们更轻松地创建出能够拥有复杂搜索功能的应用。