pgvector-haystack 0.0.1__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/.gitignore +1 -0
  2. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/PKG-INFO +15 -3
  3. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/README.md +12 -1
  4. pgvector_haystack-0.2.0/examples/embedding_retrieval.py +60 -0
  5. pgvector_haystack-0.2.0/pydoc/config.yml +30 -0
  6. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/pyproject.toml +22 -9
  7. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/src/haystack_integrations/components/retrievers/pgvector/__init__.py +2 -1
  8. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/src/haystack_integrations/components/retrievers/pgvector/embedding_retriever.py +67 -19
  9. pgvector_haystack-0.2.0/src/haystack_integrations/components/retrievers/pgvector/keyword_retriever.py +123 -0
  10. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/src/haystack_integrations/document_stores/pgvector/document_store.py +158 -36
  11. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/src/haystack_integrations/document_stores/pgvector/filters.py +15 -13
  12. pgvector_haystack-0.2.0/tests/conftest.py +64 -0
  13. pgvector_haystack-0.2.0/tests/test_document_store.py +229 -0
  14. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/tests/test_embedding_retrieval.py +1 -0
  15. pgvector_haystack-0.2.0/tests/test_filters.py +191 -0
  16. pgvector_haystack-0.2.0/tests/test_keyword_retrieval.py +50 -0
  17. pgvector_haystack-0.2.0/tests/test_retrievers.py +213 -0
  18. pgvector_haystack-0.0.1/tests/conftest.py +0 -24
  19. pgvector_haystack-0.0.1/tests/test_document_store.py +0 -222
  20. pgvector_haystack-0.0.1/tests/test_filters.py +0 -179
  21. pgvector_haystack-0.0.1/tests/test_retriever.py +0 -112
  22. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/LICENSE.txt +0 -0
  23. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/src/haystack_integrations/document_stores/pgvector/__init__.py +0 -0
  24. {pgvector_haystack-0.0.1 → pgvector_haystack-0.2.0}/tests/__init__.py +0 -0
@@ -134,3 +134,4 @@ dmypy.json
134
134
 
135
135
  # Docs generation artifacts
136
136
  _readme_*.md
137
+ .idea
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: pgvector-haystack
3
- Version: 0.0.1
3
+ Version: 0.2.0
4
4
  Summary: An integration of pgvector (vector search extension for Postgres) with Haystack
5
5
  Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations
6
6
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/pgvector/README.md
@@ -9,6 +9,7 @@ Author-email: deepset GmbH <info@deepset.ai>
9
9
  License-Expression: Apache-2.0
10
10
  License-File: LICENSE.txt
11
11
  Classifier: Development Status :: 4 - Beta
12
+ Classifier: License :: OSI Approved :: Apache Software License
12
13
  Classifier: Programming Language :: Python
13
14
  Classifier: Programming Language :: Python :: 3.8
14
15
  Classifier: Programming Language :: Python :: 3.9
@@ -45,12 +46,23 @@ pip install pgvector-haystack
45
46
 
46
47
  ## Testing
47
48
 
48
- TODO
49
+ Ensure that you have a PostgreSQL running with the `pgvector` extension. For a quick setup using Docker, run:
50
+ ```
51
+ docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres ankane/pgvector
52
+ ```
53
+
54
+ then run the tests:
49
55
 
50
56
  ```console
51
57
  hatch run test
52
58
  ```
53
59
 
60
+ To run the coverage report:
61
+
62
+ ```console
63
+ hatch run cov
64
+ ```
65
+
54
66
  ## License
55
67
 
56
68
  `pgvector-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -20,12 +20,23 @@ pip install pgvector-haystack
20
20
 
21
21
  ## Testing
22
22
 
23
- TODO
23
+ Ensure that you have a PostgreSQL running with the `pgvector` extension. For a quick setup using Docker, run:
24
+ ```
25
+ docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres ankane/pgvector
26
+ ```
27
+
28
+ then run the tests:
24
29
 
25
30
  ```console
26
31
  hatch run test
27
32
  ```
28
33
 
34
+ To run the coverage report:
35
+
36
+ ```console
37
+ hatch run cov
38
+ ```
39
+
29
40
  ## License
30
41
 
31
42
  `pgvector-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -0,0 +1,60 @@
1
+ # Before running this example, ensure you have PostgreSQL installed with the pgvector extension.
2
+ # For a quick setup using Docker:
3
+ # docker run -d -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres
4
+ # -e POSTGRES_DB=postgres ankane/pgvector
5
+
6
+ # Install required packages for this example, including pgvector-haystack and other libraries needed
7
+ # for Markdown conversion and embeddings generation. Use the following command:
8
+ # pip install pgvector-haystack markdown-it-py mdit_plain "sentence-transformers>=2.2.0"
9
+
10
+ # Download some Markdown files to index.
11
+ # git clone https://github.com/anakin87/neural-search-pills
12
+
13
+ import glob
14
+
15
+ from haystack import Pipeline
16
+ from haystack.components.converters import MarkdownToDocument
17
+ from haystack.components.embedders import SentenceTransformersDocumentEmbedder, SentenceTransformersTextEmbedder
18
+ from haystack.components.preprocessors import DocumentSplitter
19
+ from haystack.components.writers import DocumentWriter
20
+ from haystack_integrations.components.retrievers.pgvector import PgvectorEmbeddingRetriever
21
+ from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
22
+
23
+ # Set an environment variable `PG_CONN_STR` with the connection string to your PostgreSQL database.
24
+ # e.g., "postgresql://USER:PASSWORD@HOST:PORT/DB_NAME"
25
+
26
+ # Initialize PgvectorDocumentStore
27
+ document_store = PgvectorDocumentStore(
28
+ table_name="haystack_test",
29
+ embedding_dimension=768,
30
+ vector_function="cosine_similarity",
31
+ recreate_table=True,
32
+ search_strategy="hnsw",
33
+ )
34
+
35
+ # Create the indexing Pipeline and index some documents
36
+ file_paths = glob.glob("neural-search-pills/pills/*.md")
37
+
38
+
39
+ indexing = Pipeline()
40
+ indexing.add_component("converter", MarkdownToDocument())
41
+ indexing.add_component("splitter", DocumentSplitter(split_by="sentence", split_length=2))
42
+ indexing.add_component("embedder", SentenceTransformersDocumentEmbedder())
43
+ indexing.add_component("writer", DocumentWriter(document_store))
44
+ indexing.connect("converter", "splitter")
45
+ indexing.connect("splitter", "embedder")
46
+ indexing.connect("embedder", "writer")
47
+
48
+ indexing.run({"converter": {"sources": file_paths}})
49
+
50
+ # Create the querying Pipeline and try a query
51
+ querying = Pipeline()
52
+ querying.add_component("embedder", SentenceTransformersTextEmbedder())
53
+ querying.add_component("retriever", PgvectorEmbeddingRetriever(document_store=document_store, top_k=3))
54
+ querying.connect("embedder", "retriever")
55
+
56
+ results = querying.run({"embedder": {"text": "What is a cross-encoder?"}})
57
+
58
+ for doc in results["retriever"]["documents"]:
59
+ print(doc)
60
+ print("-" * 10)
@@ -0,0 +1,30 @@
1
+ loaders:
2
+ - type: haystack_pydoc_tools.loaders.CustomPythonLoader
3
+ search_path: [../src]
4
+ modules: [
5
+ "haystack_integrations.components.retrievers.pgvector.embedding_retriever",
6
+ "haystack_integrations.document_stores.pgvector.document_store",
7
+ ]
8
+ ignore_when_discovered: ["__init__"]
9
+ processors:
10
+ - type: filter
11
+ expression:
12
+ documented_only: true
13
+ do_not_filter_modules: false
14
+ skip_empty_modules: true
15
+ - type: smart
16
+ - type: crossref
17
+ renderer:
18
+ type: haystack_pydoc_tools.renderers.ReadmeIntegrationRenderer
19
+ excerpt: Pgvector integration for Haystack
20
+ category_slug: integrations-api
21
+ title: Pgvector
22
+ slug: integrations-pgvector
23
+ order: 190
24
+ markdown:
25
+ descriptive_class_title: false
26
+ classdef_code_block: false
27
+ descriptive_module_title: true
28
+ add_method_class_prefix: true
29
+ add_member_class_prefix: false
30
+ filename: _readme_pgvector.md
@@ -14,6 +14,7 @@ authors = [
14
14
  { name = "deepset GmbH", email = "info@deepset.ai" },
15
15
  ]
16
16
  classifiers = [
17
+ "License :: OSI Approved :: Apache Software License",
17
18
  "Development Status :: 4 - Beta",
18
19
  "Programming Language :: Python",
19
20
  "Programming Language :: Python :: 3.8",
@@ -51,6 +52,7 @@ dependencies = [
51
52
  "coverage[toml]>=6.5",
52
53
  "pytest",
53
54
  "ipython",
55
+ "haystack-pydoc-tools",
54
56
  ]
55
57
  [tool.hatch.envs.default.scripts]
56
58
  test = "pytest {args:tests}"
@@ -63,6 +65,9 @@ cov = [
63
65
  "test-cov",
64
66
  "cov-report",
65
67
  ]
68
+ docs = [
69
+ "pydoc-markdown pydoc/config.yml"
70
+ ]
66
71
 
67
72
  [[tool.hatch.envs.all.matrix]]
68
73
  python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
@@ -91,12 +96,12 @@ all = [
91
96
  ]
92
97
 
93
98
  [tool.black]
94
- target-version = ["py37"]
99
+ target-version = ["py38"]
95
100
  line-length = 120
96
101
  skip-string-normalization = true
97
102
 
98
103
  [tool.ruff]
99
- target-version = "py37"
104
+ target-version = "py38"
100
105
  line-length = 120
101
106
  select = [
102
107
  "A",
@@ -134,6 +139,8 @@ ignore = [
134
139
  "S105", "S106", "S107",
135
140
  # Ignore complexity
136
141
  "C901", "PLR0911", "PLR0912", "PLR0913", "PLR0915",
142
+ # ignore function-call-in-default-argument
143
+ "B008",
137
144
  ]
138
145
  unfixable = [
139
146
  # Don't touch unused imports
@@ -149,24 +156,30 @@ ban-relative-imports = "parents"
149
156
  [tool.ruff.per-file-ignores]
150
157
  # Tests can use magic values, assertions, and relative imports
151
158
  "tests/**/*" = ["PLR2004", "S101", "TID252"]
159
+ # examples can contain "print" commands
160
+ "examples/**/*" = ["T201"]
161
+
152
162
 
153
163
  [tool.coverage.run]
154
- source_pkgs = ["src", "tests"]
164
+ source = ["haystack_integrations"]
155
165
  branch = true
156
- parallel = true
157
-
158
-
159
- [tool.coverage.paths]
160
- weaviate_haystack = ["src/haystack_integrations", "*/pgvector-haystack/src"]
161
- tests = ["tests", "*/pgvector-haystack/tests"]
166
+ parallel = false
162
167
 
163
168
  [tool.coverage.report]
169
+ omit = ["*/tests/*", "*/__init__.py"]
170
+ show_missing=true
164
171
  exclude_lines = [
165
172
  "no cov",
166
173
  "if __name__ == .__main__.:",
167
174
  "if TYPE_CHECKING:",
168
175
  ]
169
176
 
177
+ [tool.pytest.ini_options]
178
+ markers = [
179
+ "integration: integration tests"
180
+ ]
181
+
182
+
170
183
  [[tool.mypy.overrides]]
171
184
  module = [
172
185
  "haystack.*",
@@ -2,5 +2,6 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
  from .embedding_retriever import PgvectorEmbeddingRetriever
5
+ from .keyword_retriever import PgvectorKeywordRetriever
5
6
 
6
- __all__ = ["PgvectorEmbeddingRetriever"]
7
+ __all__ = ["PgvectorEmbeddingRetriever", "PgvectorKeywordRetriever"]
@@ -12,9 +12,47 @@ from haystack_integrations.document_stores.pgvector.document_store import VALID_
12
12
  @component
13
13
  class PgvectorEmbeddingRetriever:
14
14
  """
15
- Retrieves documents from the PgvectorDocumentStore, based on their dense embeddings.
15
+ Retrieves documents from the `PgvectorDocumentStore`, based on their dense embeddings.
16
16
 
17
- Needs to be connected to the PgvectorDocumentStore.
17
+ Example usage:
18
+ ```python
19
+ from haystack.document_stores import DuplicatePolicy
20
+ from haystack import Document, Pipeline
21
+ from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
22
+
23
+ from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
24
+ from haystack_integrations.components.retrievers.pgvector import PgvectorEmbeddingRetriever
25
+
26
+ # Set an environment variable `PG_CONN_STR` with the connection string to your PostgreSQL database.
27
+ # e.g., "postgresql://USER:PASSWORD@HOST:PORT/DB_NAME"
28
+
29
+ document_store = PgvectorDocumentStore(
30
+ embedding_dimension=768,
31
+ vector_function="cosine_similarity",
32
+ recreate_table=True,
33
+ )
34
+
35
+ documents = [Document(content="There are over 7,000 languages spoken around the world today."),
36
+ Document(content="Elephants have been observed to behave in a way that indicates..."),
37
+ Document(content="In certain places, you can witness the phenomenon of bioluminescent waves.")]
38
+
39
+ document_embedder = SentenceTransformersDocumentEmbedder()
40
+ document_embedder.warm_up()
41
+ documents_with_embeddings = document_embedder.run(documents)
42
+
43
+ document_store.write_documents(documents_with_embeddings.get("documents"), policy=DuplicatePolicy.OVERWRITE)
44
+
45
+ query_pipeline = Pipeline()
46
+ query_pipeline.add_component("text_embedder", SentenceTransformersTextEmbedder())
47
+ query_pipeline.add_component("retriever", PgvectorEmbeddingRetriever(document_store=document_store))
48
+ query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
49
+
50
+ query = "How many languages are there?"
51
+
52
+ res = query_pipeline.run({"text_embedder": {"text": query}})
53
+
54
+ assert res['retriever']['documents'][0].content == "There are over 7,000 languages spoken around the world today."
55
+ ```
18
56
  """
19
57
 
20
58
  def __init__(
@@ -26,23 +64,20 @@ class PgvectorEmbeddingRetriever:
26
64
  vector_function: Optional[Literal["cosine_similarity", "inner_product", "l2_distance"]] = None,
27
65
  ):
28
66
  """
29
- Create the PgvectorEmbeddingRetriever component.
30
-
31
- :param document_store: An instance of PgvectorDocumentStore.
32
- :param filters: Filters applied to the retrieved Documents. Defaults to None.
33
- :param top_k: Maximum number of Documents to return, defaults to 10.
67
+ :param document_store: An instance of `PgvectorDocumentStore`.
68
+ :param filters: Filters applied to the retrieved Documents.
69
+ :param top_k: Maximum number of Documents to return.
34
70
  :param vector_function: The similarity function to use when searching for similar embeddings.
35
71
  Defaults to the one set in the `document_store` instance.
36
- "cosine_similarity" and "inner_product" are similarity functions and
72
+ `"cosine_similarity"` and `"inner_product"` are similarity functions and
37
73
  higher scores indicate greater similarity between the documents.
38
- "l2_distance" returns the straight-line distance between vectors,
74
+ `"l2_distance"` returns the straight-line distance between vectors,
39
75
  and the most similar documents are the ones with the smallest score.
40
-
41
- Important: if the document store is using the "hnsw" search strategy, the vector function
76
+ **Important**: if the document store is using the `"hnsw"` search strategy, the vector function
42
77
  should match the one utilized during index creation to take advantage of the index.
43
- :type vector_function: Literal["cosine_similarity", "inner_product", "l2_distance"]
44
78
 
45
- :raises ValueError: If `document_store` is not an instance of PgvectorDocumentStore.
79
+ :raises ValueError: If `document_store` is not an instance of `PgvectorDocumentStore` or if `vector_function`
80
+ is not one of the valid options.
46
81
  """
47
82
  if not isinstance(document_store, PgvectorDocumentStore):
48
83
  msg = "document_store must be an instance of PgvectorDocumentStore"
@@ -58,6 +93,12 @@ class PgvectorEmbeddingRetriever:
58
93
  self.vector_function = vector_function or document_store.vector_function
59
94
 
60
95
  def to_dict(self) -> Dict[str, Any]:
96
+ """
97
+ Serializes the component to a dictionary.
98
+
99
+ :returns:
100
+ Dictionary with serialized data.
101
+ """
61
102
  return default_to_dict(
62
103
  self,
63
104
  filters=self.filters,
@@ -68,9 +109,16 @@ class PgvectorEmbeddingRetriever:
68
109
 
69
110
  @classmethod
70
111
  def from_dict(cls, data: Dict[str, Any]) -> "PgvectorEmbeddingRetriever":
71
- data["init_parameters"]["document_store"] = default_from_dict(
72
- PgvectorDocumentStore, data["init_parameters"]["document_store"]
73
- )
112
+ """
113
+ Deserializes the component from a dictionary.
114
+
115
+ :param data:
116
+ Dictionary to deserialize from.
117
+ :returns:
118
+ Deserialized component.
119
+ """
120
+ doc_store_params = data["init_parameters"]["document_store"]
121
+ data["init_parameters"]["document_store"] = PgvectorDocumentStore.from_dict(doc_store_params)
74
122
  return default_from_dict(cls, data)
75
123
 
76
124
  @component.output_types(documents=List[Document])
@@ -82,14 +130,14 @@ class PgvectorEmbeddingRetriever:
82
130
  vector_function: Optional[Literal["cosine_similarity", "inner_product", "l2_distance"]] = None,
83
131
  ):
84
132
  """
85
- Retrieve documents from the PgvectorDocumentStore, based on their embeddings.
133
+ Retrieve documents from the `PgvectorDocumentStore`, based on their embeddings.
86
134
 
87
135
  :param query_embedding: Embedding of the query.
88
136
  :param filters: Filters applied to the retrieved Documents.
89
137
  :param top_k: Maximum number of Documents to return.
90
138
  :param vector_function: The similarity function to use when searching for similar embeddings.
91
- :type vector_function: Literal["cosine_similarity", "inner_product", "l2_distance"]
92
- :return: List of Documents similar to `query_embedding`.
139
+
140
+ :returns: List of Documents similar to `query_embedding`.
93
141
  """
94
142
  filters = filters or self.filters
95
143
  top_k = top_k or self.top_k
@@ -0,0 +1,123 @@
1
+ # SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ from typing import Any, Dict, List, Optional
5
+
6
+ from haystack import component, default_from_dict, default_to_dict
7
+ from haystack.dataclasses import Document
8
+ from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
9
+
10
+
11
+ @component
12
+ class PgvectorKeywordRetriever:
13
+ """
14
+ Retrieve documents from the `PgvectorDocumentStore`, based on keywords.
15
+
16
+ To rank the documents, the `ts_rank_cd` function of PostgreSQL is used.
17
+ It considers how often the query terms appear in the document, how close together the terms are in the document,
18
+ and how important is the part of the document where they occur.
19
+ For more details, see
20
+ [Postgres documentation](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING).
21
+
22
+ Usage example:
23
+ ```python
24
+ from haystack.document_stores import DuplicatePolicy
25
+ from haystack import Document
26
+
27
+ from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore
28
+ from haystack_integrations.components.retrievers.pgvector import PgvectorKeywordRetriever
29
+
30
+ # Set an environment variable `PG_CONN_STR` with the connection string to your PostgreSQL database.
31
+ # e.g., "postgresql://USER:PASSWORD@HOST:PORT/DB_NAME"
32
+
33
+ document_store = PgvectorDocumentStore(language="english", recreate_table=True)
34
+
35
+ documents = [Document(content="There are over 7,000 languages spoken around the world today."),
36
+ Document(content="Elephants have been observed to behave in a way that indicates..."),
37
+ Document(content="In certain places, you can witness the phenomenon of bioluminescent waves.")]
38
+
39
+ document_store.write_documents(documents_with_embeddings.get("documents"), policy=DuplicatePolicy.OVERWRITE)
40
+
41
+ retriever = PgvectorKeywordRetriever(document_store=document_store)
42
+
43
+ result = retriever.run(query="languages")
44
+
45
+ assert res['retriever']['documents'][0].content == "There are over 7,000 languages spoken around the world today."
46
+ """
47
+
48
+ def __init__(
49
+ self,
50
+ *,
51
+ document_store: PgvectorDocumentStore,
52
+ filters: Optional[Dict[str, Any]] = None,
53
+ top_k: int = 10,
54
+ ):
55
+ """
56
+ :param document_store: An instance of `PgvectorDocumentStore`.
57
+ :param filters: Filters applied to the retrieved Documents.
58
+ :param top_k: Maximum number of Documents to return.
59
+
60
+ :raises ValueError: If `document_store` is not an instance of `PgvectorDocumentStore`.
61
+ """
62
+ if not isinstance(document_store, PgvectorDocumentStore):
63
+ msg = "document_store must be an instance of PgvectorDocumentStore"
64
+ raise ValueError(msg)
65
+
66
+ self.document_store = document_store
67
+ self.filters = filters or {}
68
+ self.top_k = top_k
69
+
70
+ def to_dict(self) -> Dict[str, Any]:
71
+ """
72
+ Serializes the component to a dictionary.
73
+
74
+ :returns:
75
+ Dictionary with serialized data.
76
+ """
77
+ return default_to_dict(
78
+ self,
79
+ filters=self.filters,
80
+ top_k=self.top_k,
81
+ document_store=self.document_store.to_dict(),
82
+ )
83
+
84
+ @classmethod
85
+ def from_dict(cls, data: Dict[str, Any]) -> "PgvectorKeywordRetriever":
86
+ """
87
+ Deserializes the component from a dictionary.
88
+
89
+ :param data:
90
+ Dictionary to deserialize from.
91
+ :returns:
92
+ Deserialized component.
93
+ """
94
+ doc_store_params = data["init_parameters"]["document_store"]
95
+ data["init_parameters"]["document_store"] = PgvectorDocumentStore.from_dict(doc_store_params)
96
+ return default_from_dict(cls, data)
97
+
98
+ @component.output_types(documents=List[Document])
99
+ def run(
100
+ self,
101
+ query: str,
102
+ filters: Optional[Dict[str, Any]] = None,
103
+ top_k: Optional[int] = None,
104
+ ):
105
+ """
106
+ Retrieve documents from the `PgvectorDocumentStore`, based on keywords.
107
+
108
+ :param query: String to search in `Document`s' content.
109
+ :param filters: Filters applied to the retrieved Documents.
110
+ :param top_k: Maximum number of Documents to return.
111
+
112
+ :returns: A dictionary with the following keys:
113
+ - `documents`: List of `Document`s that match the query.
114
+ """
115
+ filters = filters or self.filters
116
+ top_k = top_k or self.top_k
117
+
118
+ docs = self.document_store._keyword_retrieval(
119
+ query=query,
120
+ filters=filters,
121
+ top_k=top_k,
122
+ )
123
+ return {"documents": docs}