发送 Search 请求
更新 books/domain/gateway/book_manager.py:
@@ -1,4 +1,5 @@
from abc import ABC, abstractmethod
+from typing import List
from ..model import Book
@@ -7,3 +8,7 @@ class BookManager(ABC):
@abstractmethod
def index_book(self, b: Book) -> str:
pass
+
+ @abstractmethod
+ def search_books(self, query: str) -> List[Book]:
+ pass
更新 books/infrastructure/search/es.py:
@@ -1,4 +1,5 @@
from dataclasses import asdict
+from typing import List
from elasticsearch import Elasticsearch
@@ -17,3 +18,12 @@ class ElasticSearchEngine(BookManager):
def index_book(self, b: Book) -> str:
result = self.client.index(index=INDEX_BOOK, document=asdict(b))
return result['_id']
+
+ def search_books(self, query: str) -> List[Book]:
+ response = self.client.search(index=INDEX_BOOK, query={
+ "multi_match": {
+ "query": query,
+ "fields": ["title", "author", "content"]
+ }
+ })
+ return [hit["_source"] for hit in response["hits"]["hits"]]
此处我们使用 multi_match
来进行多字段查询:“title”,“author”和“content”。
更新 books/application/executor/book_operator.py:
@@ -1,3 +1,5 @@
+from typing import List
+
from ...domain.model import Book
from ...domain.gateway import BookManager
@@ -9,3 +11,6 @@ class BookOperator():
def create_book(self, b: Book) -> str:
return self.book_manager.index_book(b)
+
+ def search_books(self, q: str) -> List[Book]:
+ return self.book_manager.search_books(q)
更新 books/adapter/router.py:
@@ -34,3 +34,7 @@ def make_router(app: FastAPI, wire_helper: WireHelper):
async def create_book(b: Book):
book_id = rest_handler.create_book(b)
return {"id": book_id}
+
+ @app.get("/books")
+ async def search_books(q: str):
+ return rest_handler.book_operator.search_books(q)
重启后再次使用 curl
测试:
curl 'http://localhost:8000/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."
}
]
http://localhost:8000/books?q=new%20york%20circus%20girl
在 URL 编码中,
%20
和+
都可以表示空格,但是它们的使用场景稍有区别。
赞!你刚刚完成了一个全文检索。
注意:
全文检索需要语言分词器。默认的标准分词器对中、日、韩文等语言处理效果不理想。 可以使用语言特定的分词器以获取更佳效果。