We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Poor search results
If I search on https://docs.platform.sh for "routes", I get the following results:

* https://docs.platform.sh/administration/web/configure-environment.html#routes
* https://docs.platform.sh/gettingstarted/introduction/own-code/routes-configuration.html
* https://docs.platform.sh/configuration/app/upgrading.html#platformroutesyaml
* https://docs.platform.sh/guides/gatsby/headless/drupal.html#platformroutesyaml
* https://docs.platform.sh/guides/gatsby/headless/strapi.html#platformroutesyaml
* https://docs.platform.sh/guides/gatsby/headless/wordpress.html#platformroutesyaml
* https://docs.platform.sh/guides/drupal9/deploy/configure.html#requests-configuration-routesyaml

Note the absence of the main resource on this topic: https://docs.platform.sh/configuration/routes.html

I've also tried "routes.yaml" and "configure routes" neither of which return the main routing configuration page.

The same issue appears to afflict these pages as well which seem near-impossible to locate by search:
* https://docs.platform.sh/configuration/services.html
* https://docs.platform.sh/configuration/app.html

Doing a bit of digging if I make the same search query with 1000 results limit the routes URL does not show up in the results, so perhaps it's not being indexed.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `search/main.py`
Content:
```
1 import os
2 import glob
3 import json
4 import meilisearch
5 from platformshconfig import Config
6 
7 class Search:
8     def __init__(self):
9         self.default = {
10             "host": "http://127.0.0.1",
11             "key": None,
12             "port": 7700
13         }
14 
15         self.scrape_dir = "output"
16         self.scrape_config = "config/scrape.json"
17         self.docs_index = "docs"
18         self.primaryKey = "documentId"
19         self.index_name = "Docs"
20 
21         # Below are Platform.sh custom settings for how the search engine functions.
22 
23         # Data available to the dropdown React app in docs, used to fill out autocomplete results.
24         self.displayed_attributes = ['title', 'text', 'url', 'site', 'section']
25         # Data actually searchable by our queries.
26         self.searchable_attributes = ['title', 'text', 'section']
27 
28         # Show results for one query with the listed pages, when they by default would not show up as best results. Note: these
29         # are not automatically two-way, so that's why they all appear to be defined twice.
30         self.synonyms = {
31             "routes.yaml": ["routes"],
32             "routes": ["routes.yaml"],
33             "services": ["services.yaml"],
34             "services.yaml": ["services"],
35             "application": [".platform.app.yaml", "app.yaml", "applications.yaml"],
36             ".platform.app.yaml": ["application"],
37             "app.yaml": ["application"],
38             "applications.yaml": ["application", "multi-app"],
39             "multi-app": ["applications.yaml"],
40             "regions": ["public ip addresses"],
41             "public ip addresses": ["regions"],
42             "ssl": ["https", "tls"],
43             "https": ["ssl"],
44         }
45 
46         # Ranking rules:
47         #
48         #   - Default order: ["typo", "words", "proximity", "attribute", "wordsPosition", "exactness"]
49         #
50         #   - typo: fewer typos > more typos
51         #   - words: number of times query is in document (greater number gets priority)
52         #   - proximity: smaller distance between multiple occurences of query in same document > larger distances
53         #   - attribute: sorted according to order of importance of attributes (searchable_attributes). terms in
54         #       more important attributes first.
55         #   - wordsPosition: query terms earlier in document > later in document
56         #   - exactness: similarity of matched words in document with query
57 
58         self.ranking_rules = ["asc(rank)", "attribute", "typo", "words", "proximity", "wordsPosition", "exactness"]
59 
60         self.updated_settings = {
61             "rankingRules": self.ranking_rules,
62             "searchableAttributes": self.searchable_attributes,
63             "displayedAttributes": self.displayed_attributes
64         }
65 
66         self.distinct_attribute = "url"
67 
68     def getConnectionString(self):
69         """
70         Sets the Meilisearch host string, depending on the environment.
71 
72         Returns:
73             string: Meilisearch host string.
74         """
75         if os.environ.get('PORT'):
76             return "{}:{}".format(self.default["host"], os.environ['PORT'])
77         else:
78             return "{}:{}".format(self.default["host"], self.default["port"])
79 
80     def getMasterKey(self):
81         """
82         Retrieves the Meilisearch master key, either from the Platform.sh environment or locally.
83         """
84         config = Config()
85         if config.is_valid_platform():
86             return config.projectEntropy
87         elif os.environ.get("MEILI_MASTER_KEY"):
88             return os.environ["MEILI_MASTER_KEY"]
89         else:
90             return self.default["key"]
91 
92     def add_documents(self, index):
93         """
94         Cycle through the individual site indexes in /outputs so their individual documents can be added to Meilisearch.
95         """
96         documents = [f for f in glob.glob("{}/*.json".format(self.scrape_dir))]
97         for doc in documents:
98             self.add(doc, index)
99 
100     def add(self, doc, index):
101         """
102         Add an individual site's index to the Meilisearch service.
103         """
104         with open(doc) as scraped_index:
105             data = json.load(scraped_index)
106             index.add_documents(data)
107 
108     def update(self):
109         """
110         Updates the Meilisearch index.
111         """
112         # Create a Meilisearch client.
113         client = meilisearch.Client(self.getConnectionString(), self.getMasterKey())
114 
115         # Delete previous index
116         if len(client.get_indexes()):
117             client.get_index(self.docs_index).delete()
118 
119         # Create a new index
120         index = client.create_index(uid=self.docs_index, options={'primaryKey': self.primaryKey, 'name': self.index_name})
121 
122         # Add synonyms for the index
123         index.update_synonyms(self.synonyms)
124 
125         # Update its settings: what can be searched, what's displayable, and how results should be ranked.
126         index.update_settings(self.updated_settings)
127 
128         # Update distinct attribute.
129         index.update_distinct_attribute(self.distinct_attribute)
130 
131         # Add documents to the index
132         self.add_documents(index)
133 
134 if __name__ == "__main__":
135     meili = Search()
136     meili.update()
137
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/search/main.py b/search/main.py
--- a/search/main.py
+++ b/search/main.py
@@ -23,7 +23,7 @@
         # Data available to the dropdown React app in docs, used to fill out autocomplete results.
         self.displayed_attributes = ['title', 'text', 'url', 'site', 'section']
         # Data actually searchable by our queries.
-        self.searchable_attributes = ['title', 'text', 'section']
+        self.searchable_attributes = ['title', 'text', 'url', 'section']
 
         # Show results for one query with the listed pages, when they by default would not show up as best results. Note: these
         # are not automatically two-way, so that's why they all appear to be defined twice.

{"golden_diff": "diff --git a/search/main.py b/search/main.py\n--- a/search/main.py\n+++ b/search/main.py\n@@ -23,7 +23,7 @@\n         # Data available to the dropdown React app in docs, used to fill out autocomplete results.\n         self.displayed_attributes = ['title', 'text', 'url', 'site', 'section']\n         # Data actually searchable by our queries.\n-        self.searchable_attributes = ['title', 'text', 'section']\n+        self.searchable_attributes = ['title', 'text', 'url', 'section']\n \n         # Show results for one query with the listed pages, when they by default would not show up as best results. Note: these\n         # are not automatically two-way, so that's why they all appear to be defined twice.\n", "issue": "Poor search results\nIf I search on https://docs.platform.sh for \"routes\", I get the following results:\r\n\r\n* https://docs.platform.sh/administration/web/configure-environment.html#routes\r\n* https://docs.platform.sh/gettingstarted/introduction/own-code/routes-configuration.html\r\n* https://docs.platform.sh/configuration/app/upgrading.html#platformroutesyaml\r\n* https://docs.platform.sh/guides/gatsby/headless/drupal.html#platformroutesyaml\r\n* https://docs.platform.sh/guides/gatsby/headless/strapi.html#platformroutesyaml\r\n* https://docs.platform.sh/guides/gatsby/headless/wordpress.html#platformroutesyaml\r\n* https://docs.platform.sh/guides/drupal9/deploy/configure.html#requests-configuration-routesyaml\r\n\r\nNote the absence of the main resource on this topic: https://docs.platform.sh/configuration/routes.html\r\n\r\nI've also tried \"routes.yaml\" and \"configure routes\" neither of which return the main routing configuration page.\r\n\r\nThe same issue appears to afflict these pages as well which seem near-impossible to locate by search:\r\n* https://docs.platform.sh/configuration/services.html\r\n* https://docs.platform.sh/configuration/app.html\r\n\r\nDoing a bit of digging if I make the same search query with 1000 results limit the routes URL does not show up in the results, so perhaps it's not being indexed.\n", "before_files": [{"content": "import os\nimport glob\nimport json\nimport meilisearch\nfrom platformshconfig import Config\n\nclass Search:\n    def __init__(self):\n        self.default = {\n            \"host\": \"http://127.0.0.1\",\n            \"key\": None,\n            \"port\": 7700\n        }\n\n        self.scrape_dir = \"output\"\n        self.scrape_config = \"config/scrape.json\"\n        self.docs_index = \"docs\"\n        self.primaryKey = \"documentId\"\n        self.index_name = \"Docs\"\n\n        # Below are Platform.sh custom settings for how the search engine functions.\n\n        # Data available to the dropdown React app in docs, used to fill out autocomplete results.\n        self.displayed_attributes = ['title', 'text', 'url', 'site', 'section']\n        # Data actually searchable by our queries.\n        self.searchable_attributes = ['title', 'text', 'section']\n\n        # Show results for one query with the listed pages, when they by default would not show up as best results. Note: these\n        # are not automatically two-way, so that's why they all appear to be defined twice.\n        self.synonyms = {\n            \"routes.yaml\": [\"routes\"],\n            \"routes\": [\"routes.yaml\"],\n            \"services\": [\"services.yaml\"],\n            \"services.yaml\": [\"services\"],\n            \"application\": [\".platform.app.yaml\", \"app.yaml\", \"applications.yaml\"],\n            \".platform.app.yaml\": [\"application\"],\n            \"app.yaml\": [\"application\"],\n            \"applications.yaml\": [\"application\", \"multi-app\"],\n            \"multi-app\": [\"applications.yaml\"],\n            \"regions\": [\"public ip addresses\"],\n            \"public ip addresses\": [\"regions\"],\n            \"ssl\": [\"https\", \"tls\"],\n            \"https\": [\"ssl\"],\n        }\n\n        # Ranking rules:\n        #\n        #   - Default order: [\"typo\", \"words\", \"proximity\", \"attribute\", \"wordsPosition\", \"exactness\"]\n        #\n        #   - typo: fewer typos > more typos\n        #   - words: number of times query is in document (greater number gets priority)\n        #   - proximity: smaller distance between multiple occurences of query in same document > larger distances\n        #   - attribute: sorted according to order of importance of attributes (searchable_attributes). terms in\n        #       more important attributes first.\n        #   - wordsPosition: query terms earlier in document > later in document\n        #   - exactness: similarity of matched words in document with query\n\n        self.ranking_rules = [\"asc(rank)\", \"attribute\", \"typo\", \"words\", \"proximity\", \"wordsPosition\", \"exactness\"]\n\n        self.updated_settings = {\n            \"rankingRules\": self.ranking_rules,\n            \"searchableAttributes\": self.searchable_attributes,\n            \"displayedAttributes\": self.displayed_attributes\n        }\n\n        self.distinct_attribute = \"url\"\n\n    def getConnectionString(self):\n        \"\"\"\n        Sets the Meilisearch host string, depending on the environment.\n\n        Returns:\n            string: Meilisearch host string.\n        \"\"\"\n        if os.environ.get('PORT'):\n            return \"{}:{}\".format(self.default[\"host\"], os.environ['PORT'])\n        else:\n            return \"{}:{}\".format(self.default[\"host\"], self.default[\"port\"])\n\n    def getMasterKey(self):\n        \"\"\"\n        Retrieves the Meilisearch master key, either from the Platform.sh environment or locally.\n        \"\"\"\n        config = Config()\n        if config.is_valid_platform():\n            return config.projectEntropy\n        elif os.environ.get(\"MEILI_MASTER_KEY\"):\n            return os.environ[\"MEILI_MASTER_KEY\"]\n        else:\n            return self.default[\"key\"]\n\n    def add_documents(self, index):\n        \"\"\"\n        Cycle through the individual site indexes in /outputs so their individual documents can be added to Meilisearch.\n        \"\"\"\n        documents = [f for f in glob.glob(\"{}/*.json\".format(self.scrape_dir))]\n        for doc in documents:\n            self.add(doc, index)\n\n    def add(self, doc, index):\n        \"\"\"\n        Add an individual site's index to the Meilisearch service.\n        \"\"\"\n        with open(doc) as scraped_index:\n            data = json.load(scraped_index)\n            index.add_documents(data)\n\n    def update(self):\n        \"\"\"\n        Updates the Meilisearch index.\n        \"\"\"\n        # Create a Meilisearch client.\n        client = meilisearch.Client(self.getConnectionString(), self.getMasterKey())\n\n        # Delete previous index\n        if len(client.get_indexes()):\n            client.get_index(self.docs_index).delete()\n\n        # Create a new index\n        index = client.create_index(uid=self.docs_index, options={'primaryKey': self.primaryKey, 'name': self.index_name})\n\n        # Add synonyms for the index\n        index.update_synonyms(self.synonyms)\n\n        # Update its settings: what can be searched, what's displayable, and how results should be ranked.\n        index.update_settings(self.updated_settings)\n\n        # Update distinct attribute.\n        index.update_distinct_attribute(self.distinct_attribute)\n\n        # Add documents to the index\n        self.add_documents(index)\n\nif __name__ == \"__main__\":\n    meili = Search()\n    meili.update()\n", "path": "search/main.py"}], "after_files": [{"content": "import os\nimport glob\nimport json\nimport meilisearch\nfrom platformshconfig import Config\n\nclass Search:\n    def __init__(self):\n        self.default = {\n            \"host\": \"http://127.0.0.1\",\n            \"key\": None,\n            \"port\": 7700\n        }\n\n        self.scrape_dir = \"output\"\n        self.scrape_config = \"config/scrape.json\"\n        self.docs_index = \"docs\"\n        self.primaryKey = \"documentId\"\n        self.index_name = \"Docs\"\n\n        # Below are Platform.sh custom settings for how the search engine functions.\n\n        # Data available to the dropdown React app in docs, used to fill out autocomplete results.\n        self.displayed_attributes = ['title', 'text', 'url', 'site', 'section']\n        # Data actually searchable by our queries.\n        self.searchable_attributes = ['title', 'text', 'url', 'section']\n\n        # Show results for one query with the listed pages, when they by default would not show up as best results. Note: these\n        # are not automatically two-way, so that's why they all appear to be defined twice.\n        self.synonyms = {\n            \"routes.yaml\": [\"routes\"],\n            \"routes\": [\"routes.yaml\"],\n            \"services\": [\"services.yaml\"],\n            \"services.yaml\": [\"services\"],\n            \"application\": [\".platform.app.yaml\", \"app.yaml\", \"applications.yaml\"],\n            \".platform.app.yaml\": [\"application\"],\n            \"app.yaml\": [\"application\"],\n            \"applications.yaml\": [\"application\", \"multi-app\"],\n            \"multi-app\": [\"applications.yaml\"],\n            \"regions\": [\"public ip addresses\"],\n            \"public ip addresses\": [\"regions\"],\n            \"ssl\": [\"https\", \"tls\"],\n            \"https\": [\"ssl\"],\n        }\n\n        # Ranking rules:\n        #\n        #   - Default order: [\"typo\", \"words\", \"proximity\", \"attribute\", \"wordsPosition\", \"exactness\"]\n        #\n        #   - typo: fewer typos > more typos\n        #   - words: number of times query is in document (greater number gets priority)\n        #   - proximity: smaller distance between multiple occurences of query in same document > larger distances\n        #   - attribute: sorted according to order of importance of attributes (searchable_attributes). terms in\n        #       more important attributes first.\n        #   - wordsPosition: query terms earlier in document > later in document\n        #   - exactness: similarity of matched words in document with query\n\n        self.ranking_rules = [\"asc(rank)\", \"attribute\", \"typo\", \"words\", \"proximity\", \"wordsPosition\", \"exactness\"]\n\n        self.updated_settings = {\n            \"rankingRules\": self.ranking_rules,\n            \"searchableAttributes\": self.searchable_attributes,\n            \"displayedAttributes\": self.displayed_attributes\n        }\n\n        self.distinct_attribute = \"url\"\n\n    def getConnectionString(self):\n        \"\"\"\n        Sets the Meilisearch host string, depending on the environment.\n\n        Returns:\n            string: Meilisearch host string.\n        \"\"\"\n        if os.environ.get('PORT'):\n            return \"{}:{}\".format(self.default[\"host\"], os.environ['PORT'])\n        else:\n            return \"{}:{}\".format(self.default[\"host\"], self.default[\"port\"])\n\n    def getMasterKey(self):\n        \"\"\"\n        Retrieves the Meilisearch master key, either from the Platform.sh environment or locally.\n        \"\"\"\n        config = Config()\n        if config.is_valid_platform():\n            return config.projectEntropy\n        elif os.environ.get(\"MEILI_MASTER_KEY\"):\n            return os.environ[\"MEILI_MASTER_KEY\"]\n        else:\n            return self.default[\"key\"]\n\n    def add_documents(self, index):\n        \"\"\"\n        Cycle through the individual site indexes in /outputs so their individual documents can be added to Meilisearch.\n        \"\"\"\n        documents = [f for f in glob.glob(\"{}/*.json\".format(self.scrape_dir))]\n        for doc in documents:\n            self.add(doc, index)\n\n    def add(self, doc, index):\n        \"\"\"\n        Add an individual site's index to the Meilisearch service.\n        \"\"\"\n        with open(doc) as scraped_index:\n            data = json.load(scraped_index)\n            index.add_documents(data)\n\n    def update(self):\n        \"\"\"\n        Updates the Meilisearch index.\n        \"\"\"\n        # Create a Meilisearch client.\n        client = meilisearch.Client(self.getConnectionString(), self.getMasterKey())\n\n        # Delete previous index\n        if len(client.get_indexes()):\n            client.get_index(self.docs_index).delete()\n\n        # Create a new index\n        index = client.create_index(uid=self.docs_index, options={'primaryKey': self.primaryKey, 'name': self.index_name})\n\n        # Add synonyms for the index\n        index.update_synonyms(self.synonyms)\n\n        # Update its settings: what can be searched, what's displayable, and how results should be ranked.\n        index.update_settings(self.updated_settings)\n\n        # Update distinct attribute.\n        index.update_distinct_attribute(self.distinct_attribute)\n\n        # Add documents to the index\n        self.add_documents(index)\n\nif __name__ == \"__main__\":\n    meili = Search()\n    meili.update()\n", "path": "search/main.py"}]}