» Python: Building Full-Text Search API with ElasticSearch » 3. Search Documents » 3.1 Send Search Requests

Send Search Requests

Update 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

Update 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"]]

Here we use multi_match to query on mutilple fields: “title“, “author“ and “content“.

Update 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)

Update 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)

Run the server again and try it with curl:

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

Example response:

[
  {
    "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."
  }
]

Try it in tools like Postman or Insomnia:

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

In URL encoding, both %20 and + are used for representing spaces, but they serve slightly different purposes depending on the context.

Insomnia Screenshot

Great! You just completed a full-text search.

Note:
Full text search requires language analyzers. The default analyzer is the standard analyzer, which may not be the best especially for Chinese, Japanese, or Korean text. With language specific analyzers, you can get better search experience.

PrevNext