» Node.js:使用ElasticSearch构建全文检索API » 3. 搜索文档 » 3.1 发送 Search 请求

发送 Search 请求

更新 src/domain/gateway/book_manager.ts:

@@ -2,4 +2,5 @@ import { Book } from "../model";
 
 export interface BookManager {
   indexBook(b: Book): Promise<string>;
+  searchBooks(q: string): Promise<Book[]>;
 }

更新 src/infrastructure/search/es.ts:

@@ -21,4 +21,17 @@ export class ElasticSearchEngine implements BookManager {
     });
     return result._id;
   }
+
+  async searchBooks(q: string): Promise<Book[]> {
+    const result = await this.client.search({
+      index: INDEX_BOOK,
+      query: {
+        multi_match: {
+          query: q,
+          fields: ["title", "author", "content"],
+        },
+      },
+    });
+    return result.hits.hits.map((hit) => hit._source as Book);
+  }
 }

此处我们使用 multi_match 来进行多字段查询:“title”,“author”和“content”。

更新 src/application/executor/book_operator.ts

@@ -11,4 +11,8 @@ export class BookOperator {
   async createBook(b: Book): Promise<string> {
     return await this.bookManager.indexBook(b);
   }
+
+  async searchBooks(q: string): Promise<Book[]> {
+    return await this.bookManager.searchBooks(q);
+  }
 }

更新 src/adapter/router.ts

@@ -21,6 +21,18 @@ class RestHandler {
       res.status(404).json({ error: "Failed to create" });
     }
   }
+
+  public async searchBooks(req: Request, res: Response): Promise<void> {
+    try {
+      const books = await this.bookOperator.searchBooks(
+        (req.query.q as string) || ""
+      );
+      res.status(201).json(books);
+    } catch (err) {
+      console.error(`Failed to search books: ${err}`);
+      res.status(404).json({ error: "Failed to search" });
+    }
+  }
 }
 
 // Create router
@@ -34,6 +46,7 @@ function MakeRouter(wireHelper: WireHelper): express.Router {
     res.json({ status: "ok" });
   });
   router.post("/books", restHandler.createBook.bind(restHandler));
+  router.get("/books", restHandler.searchBooks.bind(restHandler));
   return router;
 }

重启后再次使用 curl 测试:

curl 'http://localhost:3000/books?q=katniss+hunger'

样例响应:

[
  {
    "title": "The Hunger Games",
    "author": "Suzanne Collins",
    "published_at": "2008-09-14",
    "content": "In a dystopian future, teenagers are forced to participate in a televised death match called the Hunger Games. Katniss Everdeen volunteers to take her sister‘s place and becomes a symbol of rebellion."
  }
]

PostmanInsomnia 之类工具中尝试:

http://localhost:3000/books?q=new%20york%20circus%20girl

在 URL 编码中,%20+ 都可以表示空格,但是它们的使用场景稍有区别。

Insomnia Screenshot

赞!你刚刚完成了一个全文检索。

注意:
全文检索需要语言分词器。默认的标准分词器对中、日、韩文等语言处理效果不理想。 可以使用语言特定的分词器以获取更佳效果。