We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
🐛 Allow searching for code strings with separators
### Where on docs.platform.sh should be changed?

The search

### What exactly should be updated?

Searching for strings with separators like `X-Frame-Options` and `memory_ratio` don't show the results for pages that have those strings directly. Putting quotes around the strings doesn't help.

We'd like people to be able to get info on specific properties and strings, so the search should return these results.

### Additional context

_No response_

--- 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 = ['keywords', 'title', 'text', 'url', 'site', 'section']
25         # Data actually searchable by our queries.
26         self.searchable_attributes = ['keywords', 'title', 'pageUrl', 'section', 'text', 'url']
27 
28         # Show results for one query with the listed pages, when they by default would not show up as best results.
29         # Note: these aren't automatically two-way, which is why they're all defined twice.
30         self.synonyms = {
31             "cron": ["crons"],
32             "crons": ["cron tasks", "cron jobs"],
33             "e-mail": ["email"],
34             "routes.yaml": ["routes"],
35             "routes": ["routes.yaml"],
36             "services": ["services.yaml"],
37             "services.yaml": ["services"],
38             "application": [".platform.app.yaml", "app.yaml", "applications.yaml"],
39             ".platform.app.yaml": ["application"],
40             "app.yaml": ["application"],
41             "applications.yaml": ["application", "multi-app"],
42             "multi-app": ["applications.yaml"],
43             "regions": ["public ip addresses"],
44             "public ip addresses": ["regions"],
45             "ssl": ["https", "tls"],
46             "https": ["ssl"],
47             "auth": ["authentication", "access control"], # Only needs to be one way since we don't use "auth" in the docs
48         }
49 
50         # Ranking rules:
51         #
52         #   - Default order: ["words", "typo", "proximity", "attribute", "sort", "exactness"]
53         #
54         #   - words: number of times query is in document (greater number gets priority)
55         #   - typo: fewer typos > more typos
56         #   - proximity: smaller distance between multiple occurences of query in same document > larger distances
57         #   - attribute: sorted according to order of importance of attributes (searchable_attributes). terms in
58         #       more important attributes first.
59         #   - sort: queries are sorted at query time
60         #   - exactness: similarity of matched words in document with query
61 
62         self.ranking_rules = ["rank:asc", "attribute", "typo", "words", "proximity", "exactness"]
63 
64         self.updated_settings = {
65             "rankingRules": self.ranking_rules,
66             "searchableAttributes": self.searchable_attributes,
67             "displayedAttributes": self.displayed_attributes
68         }
69 
70         # Group results by page
71         self.distinct_attribute = "pageUrl"
72 
73     def getConnectionString(self):
74         """
75         Sets the Meilisearch host string, depending on the environment.
76 
77         Returns:
78             string: Meilisearch host string.
79         """
80         if os.environ.get('PORT'):
81             return "{}:{}".format(self.default["host"], os.environ['PORT'])
82         else:
83             return "{}:{}".format(self.default["host"], self.default["port"])
84 
85     def getMasterKey(self):
86         """
87         Retrieves the Meilisearch master key, either from the Platform.sh environment or locally.
88         """
89         config = Config()
90         if config.is_valid_platform():
91             return config.projectEntropy
92         elif os.environ.get("MEILI_MASTER_KEY"):
93             return os.environ["MEILI_MASTER_KEY"]
94         else:
95             return self.default["key"]
96 
97     def add_documents(self, index):
98         """
99         Cycle through the individual site indexes in /outputs so their individual documents can be added to Meilisearch.
100         """
101         documents = [f for f in glob.glob("{}/*.json".format(self.scrape_dir))]
102         for doc in documents:
103             self.add(doc, index)
104 
105     def add(self, doc, index):
106         """
107         Add an individual site's index to the Meilisearch service.
108         """
109         with open(doc) as scraped_index:
110             data = json.load(scraped_index)
111             index.add_documents(data)
112 
113     def update(self):
114         """
115         Updates the Meilisearch index.
116         """
117         # Create a Meilisearch client.
118         client = meilisearch.Client(self.getConnectionString(), self.getMasterKey())
119 
120         # Delete previous index
121         if len(client.get_indexes()):
122             client.index(self.docs_index).delete()
123 
124         # Create a new index
125         create_index_task = client.create_index(uid=self.docs_index, options={'primaryKey': self.primaryKey, 'uid': self.index_name})
126 
127         client.wait_for_task(create_index_task['uid'])
128 
129         index = client.get_index(create_index_task['indexUid'])
130 
131         # Add synonyms for the index
132         index.update_synonyms(self.synonyms)
133 
134         # Update its settings: what can be searched, what's displayable, and how results should be ranked.
135         index.update_settings(self.updated_settings)
136 
137         # Update distinct attribute.
138         index.update_distinct_attribute(self.distinct_attribute)
139 
140         # Add documents to the index
141         self.add_documents(index)
142 
143 if __name__ == "__main__":
144     meili = Search()
145     meili.update()
146
```
--- 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
@@ -59,7 +59,7 @@
         #   - sort: queries are sorted at query time
         #   - exactness: similarity of matched words in document with query
 
-        self.ranking_rules = ["rank:asc", "attribute", "typo", "words", "proximity", "exactness"]
+        self.ranking_rules = ["rank:asc", "exactness", "attribute", "proximity", "typo", "words"]
 
         self.updated_settings = {
             "rankingRules": self.ranking_rules,

{"golden_diff": "diff --git a/search/main.py b/search/main.py\n--- a/search/main.py\n+++ b/search/main.py\n@@ -59,7 +59,7 @@\n         #   - sort: queries are sorted at query time\n         #   - exactness: similarity of matched words in document with query\n \n-        self.ranking_rules = [\"rank:asc\", \"attribute\", \"typo\", \"words\", \"proximity\", \"exactness\"]\n+        self.ranking_rules = [\"rank:asc\", \"exactness\", \"attribute\", \"proximity\", \"typo\", \"words\"]\n \n         self.updated_settings = {\n             \"rankingRules\": self.ranking_rules,\n", "issue": "\ud83d\udc1b Allow searching for code strings with separators\n### Where on docs.platform.sh should be changed?\r\n\r\nThe search\r\n\r\n### What exactly should be updated?\r\n\r\nSearching for strings with separators like `X-Frame-Options` and `memory_ratio` don't show the results for pages that have those strings directly. Putting quotes around the strings doesn't help.\r\n\r\nWe'd like people to be able to get info on specific properties and strings, so the search should return these results.\r\n\r\n### Additional context\r\n\r\n_No response_\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 = ['keywords', 'title', 'text', 'url', 'site', 'section']\n        # Data actually searchable by our queries.\n        self.searchable_attributes = ['keywords', 'title', 'pageUrl', 'section', 'text', 'url']\n\n        # Show results for one query with the listed pages, when they by default would not show up as best results.\n        # Note: these aren't automatically two-way, which is why they're all defined twice.\n        self.synonyms = {\n            \"cron\": [\"crons\"],\n            \"crons\": [\"cron tasks\", \"cron jobs\"],\n            \"e-mail\": [\"email\"],\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            \"auth\": [\"authentication\", \"access control\"], # Only needs to be one way since we don't use \"auth\" in the docs\n        }\n\n        # Ranking rules:\n        #\n        #   - Default order: [\"words\", \"typo\", \"proximity\", \"attribute\", \"sort\", \"exactness\"]\n        #\n        #   - words: number of times query is in document (greater number gets priority)\n        #   - typo: fewer typos > more typos\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        #   - sort: queries are sorted at query time\n        #   - exactness: similarity of matched words in document with query\n\n        self.ranking_rules = [\"rank:asc\", \"attribute\", \"typo\", \"words\", \"proximity\", \"exactness\"]\n\n        self.updated_settings = {\n            \"rankingRules\": self.ranking_rules,\n            \"searchableAttributes\": self.searchable_attributes,\n            \"displayedAttributes\": self.displayed_attributes\n        }\n\n        # Group results by page\n        self.distinct_attribute = \"pageUrl\"\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.index(self.docs_index).delete()\n\n        # Create a new index\n        create_index_task = client.create_index(uid=self.docs_index, options={'primaryKey': self.primaryKey, 'uid': self.index_name})\n\n        client.wait_for_task(create_index_task['uid'])\n\n        index = client.get_index(create_index_task['indexUid'])\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 = ['keywords', 'title', 'text', 'url', 'site', 'section']\n        # Data actually searchable by our queries.\n        self.searchable_attributes = ['keywords', 'title', 'pageUrl', 'section', 'text', 'url']\n\n        # Show results for one query with the listed pages, when they by default would not show up as best results.\n        # Note: these aren't automatically two-way, which is why they're all defined twice.\n        self.synonyms = {\n            \"cron\": [\"crons\"],\n            \"crons\": [\"cron tasks\", \"cron jobs\"],\n            \"e-mail\": [\"email\"],\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            \"auth\": [\"authentication\", \"access control\"], # Only needs to be one way since we don't use \"auth\" in the docs\n        }\n\n        # Ranking rules:\n        #\n        #   - Default order: [\"words\", \"typo\", \"proximity\", \"attribute\", \"sort\", \"exactness\"]\n        #\n        #   - words: number of times query is in document (greater number gets priority)\n        #   - typo: fewer typos > more typos\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        #   - sort: queries are sorted at query time\n        #   - exactness: similarity of matched words in document with query\n\n        self.ranking_rules = [\"rank:asc\", \"exactness\", \"attribute\", \"proximity\", \"typo\", \"words\"]\n\n        self.updated_settings = {\n            \"rankingRules\": self.ranking_rules,\n            \"searchableAttributes\": self.searchable_attributes,\n            \"displayedAttributes\": self.displayed_attributes\n        }\n\n        # Group results by page\n        self.distinct_attribute = \"pageUrl\"\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.index(self.docs_index).delete()\n\n        # Create a new index\n        create_index_task = client.create_index(uid=self.docs_index, options={'primaryKey': self.primaryKey, 'uid': self.index_name})\n\n        client.wait_for_task(create_index_task['uid'])\n\n        index = client.get_index(create_index_task['indexUid'])\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"}]}