We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Search reindex task leaves empty index.
The 'Search projects' function does not work for me on [https://pypi.org](https://pypi.org). Irrespective of the query, the search does not return any results. (Example: [https://pypi.org/search/?q=numpy](https://pypi.org/search/?q=numpy))

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `warehouse/search/tasks.py`
Content:
```
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 # http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
12 
13 import binascii
14 import urllib
15 import os
16 
17 from elasticsearch.helpers import parallel_bulk
18 from elasticsearch_dsl import serializer
19 from sqlalchemy import and_, func
20 from sqlalchemy.orm import aliased
21 import certifi
22 import elasticsearch
23 
24 from warehouse.packaging.models import (
25     Classifier, Project, Release, release_classifiers)
26 from warehouse.packaging.search import Project as ProjectDocType
27 from warehouse.search.utils import get_index
28 from warehouse import tasks
29 from warehouse.utils.db import windowed_query
30 
31 
32 def _project_docs(db):
33 
34     releases_list = (
35         db.query(Release.name, Release.version)
36         .order_by(
37             Release.name,
38             Release.is_prerelease.nullslast(),
39             Release._pypi_ordering.desc(),
40         )
41         .distinct(Release.name)
42         .subquery("release_list")
43     )
44 
45     r = aliased(Release, name="r")
46 
47     all_versions = (
48         db.query(func.array_agg(r.version))
49         .filter(r.name == Release.name)
50         .correlate(Release)
51         .as_scalar()
52         .label("all_versions")
53     )
54 
55     classifiers = (
56         db.query(func.array_agg(Classifier.classifier))
57         .select_from(release_classifiers)
58         .join(Classifier, Classifier.id == release_classifiers.c.trove_id)
59         .filter(Release.name == release_classifiers.c.name)
60         .filter(Release.version == release_classifiers.c.version)
61         .correlate(Release)
62         .as_scalar()
63         .label("classifiers")
64     )
65 
66     release_data = (
67         db.query(
68             Release.description,
69             Release.name,
70             Release.version.label("latest_version"),
71             all_versions,
72             Release.author,
73             Release.author_email,
74             Release.maintainer,
75             Release.maintainer_email,
76             Release.home_page,
77             Release.summary,
78             Release.keywords,
79             Release.platform,
80             Release.download_url,
81             Release.created,
82             classifiers,
83             Project.normalized_name,
84             Project.name,
85         )
86         .select_from(releases_list)
87         .join(Release, and_(
88             Release.name == releases_list.c.name,
89             Release.version == releases_list.c.version))
90         .outerjoin(Release.project)
91         .order_by(Release.name)
92     )
93 
94     for release in windowed_query(release_data, Release.name, 50000):
95         p = ProjectDocType.from_db(release)
96         p.full_clean()
97         yield p.to_dict(include_meta=True)
98 
99 
100 @tasks.task(ignore_result=True, acks_late=True)
101 def reindex(request):
102     """
103     Recreate the Search Index.
104     """
105     p = urllib.parse.urlparse(request.registry.settings["elasticsearch.url"])
106     client = elasticsearch.Elasticsearch(
107         [urllib.parse.urlunparse(p[:2] + ("",) * 4)],
108         verify_certs=True,
109         ca_certs=certifi.where(),
110         timeout=30,
111         retry_on_timeout=True,
112         serializer=serializer.serializer,
113     )
114     number_of_replicas = request.registry.get("elasticsearch.replicas", 0)
115     refresh_interval = request.registry.get("elasticsearch.interval", "1s")
116 
117     # We use a randomly named index so that we can do a zero downtime reindex.
118     # Essentially we'll use a randomly named index which we will use until all
119     # of the data has been reindexed, at which point we'll point an alias at
120     # our randomly named index, and then delete the old randomly named index.
121 
122     # Create the new index and associate all of our doc types with it.
123     index_base = request.registry["elasticsearch.index"]
124     random_token = binascii.hexlify(os.urandom(5)).decode("ascii")
125     new_index_name = "{}-{}".format(index_base, random_token)
126     doc_types = request.registry.get("search.doc_types", set())
127     shards = request.registry.get("elasticsearch.shards", 1)
128 
129     # Create the new index with zero replicas and index refreshes disabled
130     # while we are bulk indexing.
131     new_index = get_index(
132         new_index_name,
133         doc_types,
134         using=client,
135         shards=shards,
136         replicas=0,
137         interval="-1",
138     )
139     new_index.create(wait_for_active_shards=shards)
140 
141     # From this point on, if any error occurs, we want to be able to delete our
142     # in progress index.
143     try:
144         request.db.execute("SET statement_timeout = '600s'")
145 
146         for _ in parallel_bulk(client, _project_docs(request.db)):
147             pass
148     except:  # noqa
149         new_index.delete()
150         raise
151     finally:
152         request.db.rollback()
153         request.db.close()
154 
155     # Now that we've finished indexing all of our data we can update the
156     # replicas and refresh intervals.
157     client.indices.put_settings(
158         index=new_index_name,
159         body={
160             "index": {
161                 "number_of_replicas": number_of_replicas,
162                 "refresh_interval": refresh_interval,
163             }
164         }
165     )
166 
167     # Point the alias at our new randomly named index and delete the old index.
168     if client.indices.exists_alias(name=index_base):
169         to_delete = set()
170         actions = []
171         for name in client.indices.get_alias(name=index_base):
172             to_delete.add(name)
173             actions.append({"remove": {"index": name, "alias": index_base}})
174         actions.append({"add": {"index": new_index_name, "alias": index_base}})
175         client.indices.update_aliases({"actions": actions})
176         client.indices.delete(",".join(to_delete))
177     else:
178         client.indices.put_alias(name=index_base, index=new_index_name)
179
```
--- 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/warehouse/search/tasks.py b/warehouse/search/tasks.py
--- a/warehouse/search/tasks.py
+++ b/warehouse/search/tasks.py
@@ -94,7 +94,9 @@
     for release in windowed_query(release_data, Release.name, 50000):
         p = ProjectDocType.from_db(release)
         p.full_clean()
-        yield p.to_dict(include_meta=True)
+        doc = p.to_dict(include_meta=True)
+        doc.pop('_index', None)
+        yield doc
 
 
 @tasks.task(ignore_result=True, acks_late=True)
@@ -143,7 +145,8 @@
     try:
         request.db.execute("SET statement_timeout = '600s'")
 
-        for _ in parallel_bulk(client, _project_docs(request.db)):
+        for _ in parallel_bulk(client, _project_docs(request.db),
+                               index=new_index_name):
             pass
     except:  # noqa
         new_index.delete()

{"golden_diff": "diff --git a/warehouse/search/tasks.py b/warehouse/search/tasks.py\n--- a/warehouse/search/tasks.py\n+++ b/warehouse/search/tasks.py\n@@ -94,7 +94,9 @@\n     for release in windowed_query(release_data, Release.name, 50000):\n         p = ProjectDocType.from_db(release)\n         p.full_clean()\n-        yield p.to_dict(include_meta=True)\n+        doc = p.to_dict(include_meta=True)\n+        doc.pop('_index', None)\n+        yield doc\n \n \n @tasks.task(ignore_result=True, acks_late=True)\n@@ -143,7 +145,8 @@\n     try:\n         request.db.execute(\"SET statement_timeout = '600s'\")\n \n-        for _ in parallel_bulk(client, _project_docs(request.db)):\n+        for _ in parallel_bulk(client, _project_docs(request.db),\n+                               index=new_index_name):\n             pass\n     except:  # noqa\n         new_index.delete()\n", "issue": "Search reindex task leaves empty index.\nThe 'Search projects' function does not work for me on [https://pypi.org](https://pypi.org). Irrespective of the query, the search does not return any results. (Example: [https://pypi.org/search/?q=numpy](https://pypi.org/search/?q=numpy))\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport binascii\nimport urllib\nimport os\n\nfrom elasticsearch.helpers import parallel_bulk\nfrom elasticsearch_dsl import serializer\nfrom sqlalchemy import and_, func\nfrom sqlalchemy.orm import aliased\nimport certifi\nimport elasticsearch\n\nfrom warehouse.packaging.models import (\n    Classifier, Project, Release, release_classifiers)\nfrom warehouse.packaging.search import Project as ProjectDocType\nfrom warehouse.search.utils import get_index\nfrom warehouse import tasks\nfrom warehouse.utils.db import windowed_query\n\n\ndef _project_docs(db):\n\n    releases_list = (\n        db.query(Release.name, Release.version)\n        .order_by(\n            Release.name,\n            Release.is_prerelease.nullslast(),\n            Release._pypi_ordering.desc(),\n        )\n        .distinct(Release.name)\n        .subquery(\"release_list\")\n    )\n\n    r = aliased(Release, name=\"r\")\n\n    all_versions = (\n        db.query(func.array_agg(r.version))\n        .filter(r.name == Release.name)\n        .correlate(Release)\n        .as_scalar()\n        .label(\"all_versions\")\n    )\n\n    classifiers = (\n        db.query(func.array_agg(Classifier.classifier))\n        .select_from(release_classifiers)\n        .join(Classifier, Classifier.id == release_classifiers.c.trove_id)\n        .filter(Release.name == release_classifiers.c.name)\n        .filter(Release.version == release_classifiers.c.version)\n        .correlate(Release)\n        .as_scalar()\n        .label(\"classifiers\")\n    )\n\n    release_data = (\n        db.query(\n            Release.description,\n            Release.name,\n            Release.version.label(\"latest_version\"),\n            all_versions,\n            Release.author,\n            Release.author_email,\n            Release.maintainer,\n            Release.maintainer_email,\n            Release.home_page,\n            Release.summary,\n            Release.keywords,\n            Release.platform,\n            Release.download_url,\n            Release.created,\n            classifiers,\n            Project.normalized_name,\n            Project.name,\n        )\n        .select_from(releases_list)\n        .join(Release, and_(\n            Release.name == releases_list.c.name,\n            Release.version == releases_list.c.version))\n        .outerjoin(Release.project)\n        .order_by(Release.name)\n    )\n\n    for release in windowed_query(release_data, Release.name, 50000):\n        p = ProjectDocType.from_db(release)\n        p.full_clean()\n        yield p.to_dict(include_meta=True)\n\n\n@tasks.task(ignore_result=True, acks_late=True)\ndef reindex(request):\n    \"\"\"\n    Recreate the Search Index.\n    \"\"\"\n    p = urllib.parse.urlparse(request.registry.settings[\"elasticsearch.url\"])\n    client = elasticsearch.Elasticsearch(\n        [urllib.parse.urlunparse(p[:2] + (\"\",) * 4)],\n        verify_certs=True,\n        ca_certs=certifi.where(),\n        timeout=30,\n        retry_on_timeout=True,\n        serializer=serializer.serializer,\n    )\n    number_of_replicas = request.registry.get(\"elasticsearch.replicas\", 0)\n    refresh_interval = request.registry.get(\"elasticsearch.interval\", \"1s\")\n\n    # We use a randomly named index so that we can do a zero downtime reindex.\n    # Essentially we'll use a randomly named index which we will use until all\n    # of the data has been reindexed, at which point we'll point an alias at\n    # our randomly named index, and then delete the old randomly named index.\n\n    # Create the new index and associate all of our doc types with it.\n    index_base = request.registry[\"elasticsearch.index\"]\n    random_token = binascii.hexlify(os.urandom(5)).decode(\"ascii\")\n    new_index_name = \"{}-{}\".format(index_base, random_token)\n    doc_types = request.registry.get(\"search.doc_types\", set())\n    shards = request.registry.get(\"elasticsearch.shards\", 1)\n\n    # Create the new index with zero replicas and index refreshes disabled\n    # while we are bulk indexing.\n    new_index = get_index(\n        new_index_name,\n        doc_types,\n        using=client,\n        shards=shards,\n        replicas=0,\n        interval=\"-1\",\n    )\n    new_index.create(wait_for_active_shards=shards)\n\n    # From this point on, if any error occurs, we want to be able to delete our\n    # in progress index.\n    try:\n        request.db.execute(\"SET statement_timeout = '600s'\")\n\n        for _ in parallel_bulk(client, _project_docs(request.db)):\n            pass\n    except:  # noqa\n        new_index.delete()\n        raise\n    finally:\n        request.db.rollback()\n        request.db.close()\n\n    # Now that we've finished indexing all of our data we can update the\n    # replicas and refresh intervals.\n    client.indices.put_settings(\n        index=new_index_name,\n        body={\n            \"index\": {\n                \"number_of_replicas\": number_of_replicas,\n                \"refresh_interval\": refresh_interval,\n            }\n        }\n    )\n\n    # Point the alias at our new randomly named index and delete the old index.\n    if client.indices.exists_alias(name=index_base):\n        to_delete = set()\n        actions = []\n        for name in client.indices.get_alias(name=index_base):\n            to_delete.add(name)\n            actions.append({\"remove\": {\"index\": name, \"alias\": index_base}})\n        actions.append({\"add\": {\"index\": new_index_name, \"alias\": index_base}})\n        client.indices.update_aliases({\"actions\": actions})\n        client.indices.delete(\",\".join(to_delete))\n    else:\n        client.indices.put_alias(name=index_base, index=new_index_name)\n", "path": "warehouse/search/tasks.py"}], "after_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport binascii\nimport urllib\nimport os\n\nfrom elasticsearch.helpers import parallel_bulk\nfrom elasticsearch_dsl import serializer\nfrom sqlalchemy import and_, func\nfrom sqlalchemy.orm import aliased\nimport certifi\nimport elasticsearch\n\nfrom warehouse.packaging.models import (\n    Classifier, Project, Release, release_classifiers)\nfrom warehouse.packaging.search import Project as ProjectDocType\nfrom warehouse.search.utils import get_index\nfrom warehouse import tasks\nfrom warehouse.utils.db import windowed_query\n\n\ndef _project_docs(db):\n\n    releases_list = (\n        db.query(Release.name, Release.version)\n        .order_by(\n            Release.name,\n            Release.is_prerelease.nullslast(),\n            Release._pypi_ordering.desc(),\n        )\n        .distinct(Release.name)\n        .subquery(\"release_list\")\n    )\n\n    r = aliased(Release, name=\"r\")\n\n    all_versions = (\n        db.query(func.array_agg(r.version))\n        .filter(r.name == Release.name)\n        .correlate(Release)\n        .as_scalar()\n        .label(\"all_versions\")\n    )\n\n    classifiers = (\n        db.query(func.array_agg(Classifier.classifier))\n        .select_from(release_classifiers)\n        .join(Classifier, Classifier.id == release_classifiers.c.trove_id)\n        .filter(Release.name == release_classifiers.c.name)\n        .filter(Release.version == release_classifiers.c.version)\n        .correlate(Release)\n        .as_scalar()\n        .label(\"classifiers\")\n    )\n\n    release_data = (\n        db.query(\n            Release.description,\n            Release.name,\n            Release.version.label(\"latest_version\"),\n            all_versions,\n            Release.author,\n            Release.author_email,\n            Release.maintainer,\n            Release.maintainer_email,\n            Release.home_page,\n            Release.summary,\n            Release.keywords,\n            Release.platform,\n            Release.download_url,\n            Release.created,\n            classifiers,\n            Project.normalized_name,\n            Project.name,\n        )\n        .select_from(releases_list)\n        .join(Release, and_(\n            Release.name == releases_list.c.name,\n            Release.version == releases_list.c.version))\n        .outerjoin(Release.project)\n        .order_by(Release.name)\n    )\n\n    for release in windowed_query(release_data, Release.name, 50000):\n        p = ProjectDocType.from_db(release)\n        p.full_clean()\n        doc = p.to_dict(include_meta=True)\n        doc.pop('_index', None)\n        yield doc\n\n\n@tasks.task(ignore_result=True, acks_late=True)\ndef reindex(request):\n    \"\"\"\n    Recreate the Search Index.\n    \"\"\"\n    p = urllib.parse.urlparse(request.registry.settings[\"elasticsearch.url\"])\n    client = elasticsearch.Elasticsearch(\n        [urllib.parse.urlunparse(p[:2] + (\"\",) * 4)],\n        verify_certs=True,\n        ca_certs=certifi.where(),\n        timeout=30,\n        retry_on_timeout=True,\n        serializer=serializer.serializer,\n    )\n    number_of_replicas = request.registry.get(\"elasticsearch.replicas\", 0)\n    refresh_interval = request.registry.get(\"elasticsearch.interval\", \"1s\")\n\n    # We use a randomly named index so that we can do a zero downtime reindex.\n    # Essentially we'll use a randomly named index which we will use until all\n    # of the data has been reindexed, at which point we'll point an alias at\n    # our randomly named index, and then delete the old randomly named index.\n\n    # Create the new index and associate all of our doc types with it.\n    index_base = request.registry[\"elasticsearch.index\"]\n    random_token = binascii.hexlify(os.urandom(5)).decode(\"ascii\")\n    new_index_name = \"{}-{}\".format(index_base, random_token)\n    doc_types = request.registry.get(\"search.doc_types\", set())\n    shards = request.registry.get(\"elasticsearch.shards\", 1)\n\n    # Create the new index with zero replicas and index refreshes disabled\n    # while we are bulk indexing.\n    new_index = get_index(\n        new_index_name,\n        doc_types,\n        using=client,\n        shards=shards,\n        replicas=0,\n        interval=\"-1\",\n    )\n    new_index.create(wait_for_active_shards=shards)\n\n    # From this point on, if any error occurs, we want to be able to delete our\n    # in progress index.\n    try:\n        request.db.execute(\"SET statement_timeout = '600s'\")\n\n        for _ in parallel_bulk(client, _project_docs(request.db),\n                               index=new_index_name):\n            pass\n    except:  # noqa\n        new_index.delete()\n        raise\n    finally:\n        request.db.rollback()\n        request.db.close()\n\n    # Now that we've finished indexing all of our data we can update the\n    # replicas and refresh intervals.\n    client.indices.put_settings(\n        index=new_index_name,\n        body={\n            \"index\": {\n                \"number_of_replicas\": number_of_replicas,\n                \"refresh_interval\": refresh_interval,\n            }\n        }\n    )\n\n    # Point the alias at our new randomly named index and delete the old index.\n    if client.indices.exists_alias(name=index_base):\n        to_delete = set()\n        actions = []\n        for name in client.indices.get_alias(name=index_base):\n            to_delete.add(name)\n            actions.append({\"remove\": {\"index\": name, \"alias\": index_base}})\n        actions.append({\"add\": {\"index\": new_index_name, \"alias\": index_base}})\n        client.indices.update_aliases({\"actions\": actions})\n        client.indices.delete(\",\".join(to_delete))\n    else:\n        client.indices.put_alias(name=index_base, index=new_index_name)\n", "path": "warehouse/search/tasks.py"}]}