Skip to main content
Version: 3.2-unstable

Solr

haystack_integrations.components.retrievers.solr.bm25_retriever

SolrBM25Retriever

Fetches documents from a SolrDocumentStore using Solr's BM25 similarity.

Usage example:

python
from haystack_integrations.document_stores.solr import SolrDocumentStore
from haystack_integrations.components.retrievers.solr import SolrBM25Retriever

document_store = SolrDocumentStore(core="haystack")
retriever = SolrBM25Retriever(document_store=document_store)
result = retriever.run(query="Apache Solr")

init

python
__init__(
*,
document_store: SolrDocumentStore,
filters: dict[str, Any] | None = None,
fuzziness: int = 0,
top_k: int = 10,
scale_score: bool = False,
all_terms_must_match: bool = False,
filter_policy: str | FilterPolicy = FilterPolicy.REPLACE,
raise_on_failure: bool = True
) -> None

Create a SolrBM25Retriever.

Parameters:

  • document_store (SolrDocumentStore) – the document store to search.
  • filters (dict[str, Any] | None) – filters applied to the search. Combined with the filters passed to run according to filter_policy.
  • fuzziness (int) – per-term edit distance. 0, the default, disables fuzzy matching.
  • top_k (int) – maximum number of documents to return.
  • scale_score (bool) – whether to scale scores into the (0, 1) range.
  • all_terms_must_match (bool) – whether every query term must match.
  • filter_policy (str | FilterPolicy) – how runtime filters combine with the filters given here.
  • raise_on_failure (bool) – whether a failing search raises, or logs and returns no documents.

Raises:

  • ValueError – if document_store is not a SolrDocumentStore, or top_k is not positive.

to_dict

python
to_dict() -> dict[str, Any]

Serializes the component to a dictionary.

Returns:

  • dict[str, Any] – dictionary with serialized data.

from_dict

python
from_dict(data: dict[str, Any]) -> SolrBM25Retriever

Deserializes the component from a dictionary.

Parameters:

  • data (dict[str, Any]) – dictionary to deserialize from.

Returns:

  • SolrBM25Retriever – deserialized component.

run

python
run(
query: str,
filters: dict[str, Any] | None = None,
top_k: int | None = None,
fuzziness: int | None = None,
scale_score: bool | None = None,
all_terms_must_match: bool | None = None,
) -> dict[str, list[Document]]

Retrieve documents matching query.

Parameters:

  • query (str) – the query string.
  • filters (dict[str, Any] | None) – filters applied to the search.
  • top_k (int | None) – maximum number of documents to return.
  • fuzziness (int | None) – per-term edit distance.
  • scale_score (bool | None) – whether to scale scores into the (0, 1) range.
  • all_terms_must_match (bool | None) – whether every query term must match.

Returns:

  • dict[str, list[Document]] – a dictionary with a documents key holding the retrieved documents.

Raises:

  • ValueError – if top_k is not positive.

run_async

python
run_async(
query: str,
filters: dict[str, Any] | None = None,
top_k: int | None = None,
fuzziness: int | None = None,
scale_score: bool | None = None,
all_terms_must_match: bool | None = None,
) -> dict[str, list[Document]]

Retrieve documents matching query, asynchronously.

Parameters:

  • query (str) – the query string.
  • filters (dict[str, Any] | None) – filters applied to the search.
  • top_k (int | None) – maximum number of documents to return.
  • fuzziness (int | None) – per-term edit distance.
  • scale_score (bool | None) – whether to scale scores into the (0, 1) range.
  • all_terms_must_match (bool | None) – whether every query term must match.

Returns:

  • dict[str, list[Document]] – a dictionary with a documents key holding the retrieved documents.

Raises:

  • ValueError – if top_k is not positive.

close

python
close() -> None

Close the underlying document store connection.

close_async

python
close_async() -> None

Close the underlying document store async connection.

haystack_integrations.components.retrievers.solr.embedding_retriever

SolrEmbeddingRetriever

Fetches documents from a SolrDocumentStore using Solr's {!knn} dense vector search.

Usage example:

python
from haystack import Pipeline
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.document_stores.solr import SolrDocumentStore
from haystack_integrations.components.retrievers.solr import SolrEmbeddingRetriever

document_store = SolrDocumentStore(core="haystack", embedding_dim=384)
embedder = SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")

pipeline = Pipeline()
pipeline.add_component("embedder", embedder)
pipeline.add_component("retriever", SolrEmbeddingRetriever(document_store=document_store))
pipeline.connect("embedder.embedding", "retriever.query_embedding")

result = pipeline.run(data={"embedder": {"text": "Apache Solr"}})

init

python
__init__(
*,
document_store: SolrDocumentStore,
filters: dict[str, Any] | None = None,
top_k: int = 10,
filter_policy: str | FilterPolicy = FilterPolicy.REPLACE,
raise_on_failure: bool = True
) -> None

Create a SolrEmbeddingRetriever.

Parameters:

  • document_store (SolrDocumentStore) – the document store to search.
  • filters (dict[str, Any] | None) – filters applied to the search. Combined with the filters passed to run according to filter_policy. Filters act as a k-NN graph pre-filter, so the search still returns up to top_k documents.
  • top_k (int) – maximum number of documents to return.
  • filter_policy (str | FilterPolicy) – how runtime filters combine with the filters given here.
  • raise_on_failure (bool) – whether a failing search raises, or logs and returns no documents.

Raises:

  • ValueError – if document_store is not a SolrDocumentStore, or top_k is not positive.

to_dict

python
to_dict() -> dict[str, Any]

Serializes the component to a dictionary.

Returns:

  • dict[str, Any] – dictionary with serialized data.

from_dict

python
from_dict(data: dict[str, Any]) -> SolrEmbeddingRetriever

Deserializes the component from a dictionary.

Parameters:

  • data (dict[str, Any]) – dictionary to deserialize from.

Returns:

  • SolrEmbeddingRetriever – deserialized component.

run

python
run(
query_embedding: list[float],
filters: dict[str, Any] | None = None,
top_k: int | None = None,
) -> dict[str, list[Document]]

Retrieve documents similar to query_embedding.

Parameters:

  • query_embedding (list[float]) – the query embedding.
  • filters (dict[str, Any] | None) – filters applied to the search.
  • top_k (int | None) – maximum number of documents to return.

Returns:

  • dict[str, list[Document]] – a dictionary with a documents key holding the retrieved documents.

Raises:

  • ValueError – if top_k is not positive.

run_async

python
run_async(
query_embedding: list[float],
filters: dict[str, Any] | None = None,
top_k: int | None = None,
) -> dict[str, list[Document]]

Retrieve documents similar to query_embedding, asynchronously.

Parameters:

  • query_embedding (list[float]) – the query embedding.
  • filters (dict[str, Any] | None) – filters applied to the search.
  • top_k (int | None) – maximum number of documents to return.

Returns:

  • dict[str, list[Document]] – a dictionary with a documents key holding the retrieved documents.

Raises:

  • ValueError – if top_k is not positive.

close

python
close() -> None

Close the underlying document store connection.

close_async

python
close_async() -> None

Close the underlying document store async connection.

haystack_integrations.components.retrievers.solr.solr_hybrid_retriever

SolrHybridRetriever

Hybrid retrieval over a SolrDocumentStore, combining BM25 and dense vector search.

Wraps a pipeline that embeds the query, runs a BM25 and an embedding retriever over the same core, and fuses the two result lists with a DocumentJoiner.

Usage example:

python
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.document_stores.solr import SolrDocumentStore
from haystack_integrations.components.retrievers.solr import SolrHybridRetriever

document_store = SolrDocumentStore(core="haystack", embedding_dim=384)
retriever = SolrHybridRetriever(
document_store=document_store,
embedder=SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"),
)
retriever.warm_up()
result = retriever.run(query="Apache Solr")

init

python
__init__(
document_store: SolrDocumentStore,
*,
embedder: TextEmbedder,
filters_bm25: dict[str, Any] | None = None,
fuzziness: int = 0,
top_k_bm25: int = 10,
scale_score: bool = False,
all_terms_must_match: bool = False,
filter_policy_bm25: str | FilterPolicy = FilterPolicy.REPLACE,
filters_embedding: dict[str, Any] | None = None,
top_k_embedding: int = 10,
filter_policy_embedding: str | FilterPolicy = FilterPolicy.REPLACE,
join_mode: str | JoinMode = JoinMode.RECIPROCAL_RANK_FUSION,
weights: list[float] | None = None,
top_k: int | None = None,
sort_by_score: bool = True,
**kwargs: Any
) -> None

Create a SolrHybridRetriever.

Parameters:

  • document_store (SolrDocumentStore) – the document store both retrievers search.
  • embedder (TextEmbedder) – the text embedder turning the query into a vector.
  • filters_bm25 (dict[str, Any] | None) – filters for the BM25 branch.
  • fuzziness (int) – per-term edit distance for the BM25 branch.
  • top_k_bm25 (int) – maximum number of documents from the BM25 branch.
  • scale_score (bool) – whether to scale BM25 scores into the (0, 1) range.
  • all_terms_must_match (bool) – whether every query term must match in the BM25 branch.
  • filter_policy_bm25 (str | FilterPolicy) – filter policy for the BM25 branch.
  • filters_embedding (dict[str, Any] | None) – filters for the embedding branch.
  • top_k_embedding (int) – maximum number of documents from the embedding branch.
  • filter_policy_embedding (str | FilterPolicy) – filter policy for the embedding branch.
  • join_mode (str | JoinMode) – how the two result lists are fused.
  • weights (list[float] | None) – per-branch weights used by the joiner.
  • top_k (int | None) – maximum number of documents returned after fusion.
  • sort_by_score (bool) – whether the fused documents are sorted by score.
  • kwargs (Any) – extra init arguments for the underlying retrievers, given as bm25_retriever={...} and/or embedding_retriever={...}.

Raises:

  • ValueError – if kwargs contains a key other than those two.

warm_up

python
warm_up() -> None

Warm up the underlying pipeline components.

run

python
run(
query: str,
filters_bm25: dict[str, Any] | None = None,
filters_embedding: dict[str, Any] | None = None,
top_k_bm25: int | None = None,
top_k_embedding: int | None = None,
) -> dict[str, list[Document]]

Run the hybrid retrieval pipeline and return the retrieved documents.

to_dict

python
to_dict() -> dict[str, Any]

Serializes the component to a dictionary.

Returns:

  • dict[str, Any] – dictionary with serialized data.

from_dict

python
from_dict(data: dict[str, Any]) -> SolrHybridRetriever

Deserializes the component from a dictionary.

Parameters:

  • data (dict[str, Any]) – dictionary to deserialize from.

Returns:

  • SolrHybridRetriever – deserialized component.

close

python
close() -> None

Close the underlying document store connection.

close_async

python
close_async() -> None

Close the underlying document store async connection.

haystack_integrations.document_stores.solr.document_store

SolrDocumentStore

A Document Store for Apache Solr.

Supports keyword search through Solr's BM25 similarity and dense vector search through DenseVectorField and the {!knn} query parser. Requires Solr 9.6 or newer.

Usage example:

python
from haystack import Document
from haystack_integrations.document_stores.solr import SolrDocumentStore

store = SolrDocumentStore(url="http://localhost:8983/solr", core="haystack", embedding_dim=768)
store.write_documents([Document(content="Apache Solr is a search platform.")])

Metadata is stored in Solr fields whose names encode the Python type of the value, so metadata round-trips with its type intact. See the schema module for the details of that mapping. Metadata keys become Solr field names and must therefore consist of letters, digits and underscores.

Two things Solr cannot do:

  • Document.sparse_embedding is ignored, with a warning, because Solr has no sparse vector field.
  • Comparing content with == is a phrase match against an analysed field rather than exact string equality. Filter on a metadata field when exact matching matters.

init

python
__init__(
*,
url: str | None = None,
core: str = "haystack",
embedding_dim: int = 768,
similarity_function: Literal[
"cosine", "dot_product", "euclidean"
] = "cosine",
return_embedding: bool = False,
create_core: bool = False,
manage_schema: bool = True,
config_set: str = "_default",
vector_field_type_params: dict[str, Any] | None = None,
auth: tuple[Secret, Secret] | tuple[str, str] | None = (
Secret.from_env_var("SOLR_USERNAME", strict=False),
Secret.from_env_var("SOLR_PASSWORD", strict=False),
),
verify_certs: bool = True,
timeout: float = 30.0,
batch_size: int = DEFAULT_BATCH_SIZE,
commit: bool = True,
commit_within_ms: int | None = None,
query_page_size: int = DEFAULT_QUERY_PAGE_SIZE,
**kwargs: Any
) -> None

Create a new SolrDocumentStore.

Parameters:

  • url (str | None) – Solr base URL. Falls back to the SOLR_URL environment variable, then to http://localhost:8983/solr.
  • core (str) – name of the Solr core (or SolrCloud collection) to read from and write to.
  • embedding_dim (int) – dimension of the embeddings. Solr fixes a vector field's dimension when the field is created, so this cannot be changed for an existing core.
  • similarity_function (Literal['cosine', 'dot_product', 'euclidean']) – vector similarity to use, one of cosine, dot_product or euclidean.
  • return_embedding (bool) – whether filter_documents and the retrievers return embeddings. Leaving this False keeps large vectors off the wire.
  • create_core (bool) – whether to create the core if it does not exist. Requires the config_set to be present in Solr's configset directory (<solr_home>/configsets), which is not the case for a stock installation, so this defaults to False and most deployments should create the core out of band.
  • manage_schema (bool) – whether to create the fields the document store needs and disable Solr's schemaless field guessing. Set to False to manage the schema yourself, in which case schema.schema_payload is the definitive list of the fields and dynamic fields required.
  • config_set (str) – configset used when create_core is enabled.
  • vector_field_type_params (dict[str, Any] | None) – extra attributes for the vector field type, for example {"hnswM": 32} on Solr 10 or {"hnswMaxConnections": 32} on Solr 9. Left unset by default because Solr 10 renamed these attributes without a compatibility shim.
  • auth (tuple[Secret, Secret] | tuple[str, str] | None) – username and password for basic authentication. Reads the SOLR_USERNAME and SOLR_PASSWORD environment variables by default. Pass None to disable authentication.
  • verify_certs (bool) – whether to verify TLS certificates.
  • timeout (float) – request timeout in seconds.
  • batch_size (int) – number of documents sent per update request.
  • commit (bool) – whether writes and deletes commit immediately, making them searchable at once.
  • commit_within_ms (int | None) – ask Solr to commit within this many milliseconds instead of blocking.
  • query_page_size (int) – number of documents fetched per page when paginating.
  • kwargs (Any) – extra keyword arguments forwarded to the underlying httpx clients, for example proxy or headers.

to_dict

python
to_dict() -> dict[str, Any]

Serializes the component to a dictionary.

Returns:

  • dict[str, Any] – dictionary with serialized data.

from_dict

python
from_dict(data: dict[str, Any]) -> SolrDocumentStore

Deserializes the component from a dictionary.

Parameters:

  • data (dict[str, Any]) – dictionary to deserialize from.

Returns:

  • SolrDocumentStore – deserialized component.

close

python
close() -> None

Close the underlying HTTP client. The store reconnects on the next call.

close_async

python
close_async() -> None

Close the underlying async HTTP client. The store reconnects on the next call.

count_documents

python
count_documents() -> int

Returns how many documents are present in the document store.

Returns:

  • int – the number of documents.

count_documents_async

python
count_documents_async() -> int

Returns how many documents are present in the document store.

Returns:

  • int – the number of documents.

count_documents_by_filter

python
count_documents_by_filter(filters: dict[str, Any]) -> int

Returns how many documents match the given filters.

Parameters:

  • filters (dict[str, Any]) – the filters to apply.

Returns:

  • int – the number of matching documents.

count_documents_by_filter_async

python
count_documents_by_filter_async(filters: dict[str, Any]) -> int

Returns how many documents match the given filters.

Parameters:

  • filters (dict[str, Any]) – the filters to apply.

Returns:

  • int – the number of matching documents.

filter_documents

python
filter_documents(filters: dict[str, Any] | None = None) -> list[Document]

Returns the documents that match the filters provided.

For a detailed specification of the filters, refer to the documentation.

All Haystack operators are supported: ==, !=, >, >=, <, <=, in, not in, and the AND, OR and NOT logical operators. Three behaviours are worth knowing:

  • >, >=, < and <= accept numbers and ISO-8601 date strings. Any other string raises a FilterError, because Solr would compare it lexicographically and quietly give an answer nobody meant.
  • Because the value's Python type selects the Solr field, {"field": "meta.page", "value": 100} and {"field": "meta.page", "value": "100"} match different documents.
  • == on content is a phrase match against an analysed field, not exact equality.

Parameters:

  • filters (dict[str, Any] | None) – the filters to apply to the document list.

Returns:

  • list[Document] – a list of Documents that match the given filters.

Raises:

  • FilterError – if the filters are malformed, or compare a value Solr cannot order.

filter_documents_async

python
filter_documents_async(filters: dict[str, Any] | None = None) -> list[Document]

Returns the documents that match the filters provided.

See filter_documents for the supported operators and their caveats.

Parameters:

  • filters (dict[str, Any] | None) – the filters to apply to the document list.

Returns:

  • list[Document] – a list of Documents that match the given filters.

Raises:

  • FilterError – if the filters are malformed, or compare a value Solr cannot order.

write_documents

python
write_documents(
documents: list[Document], policy: DuplicatePolicy = DuplicatePolicy.NONE
) -> int

Writes Documents to Solr.

Metadata keys must consist of letters, digits and underscores only, because each key becomes a Solr field name. Sparse embeddings are dropped, as Solr has no sparse vector field.

Parameters:

  • documents (list[Document]) – a list of Documents to write.
  • policy (DuplicatePolicy) – the policy to apply when a Document with the same id already exists. The default DuplicatePolicy.NONE resolves to DuplicatePolicy.FAIL.

Returns:

  • int – the number of Documents written.

Raises:

  • ValueError – if documents is not a list of Documents, or a metadata key cannot be expressed as a Solr field name.
  • DuplicateDocumentError – if policy is FAIL (or the default NONE) and a Document already exists.

write_documents_async

python
write_documents_async(
documents: list[Document], policy: DuplicatePolicy = DuplicatePolicy.NONE
) -> int

Writes Documents to Solr.

Parameters:

  • documents (list[Document]) – a list of Documents to write.
  • policy (DuplicatePolicy) – the policy to apply when a Document with the same id already exists. The default DuplicatePolicy.NONE resolves to DuplicatePolicy.FAIL.

Returns:

  • int – the number of Documents written.

Raises:

  • ValueError – if documents is not a list of Documents, or a metadata key cannot be expressed as a Solr field name.
  • DuplicateDocumentError – if policy is FAIL (or the default NONE) and a Document already exists.

delete_documents

python
delete_documents(document_ids: list[str]) -> None

Deletes all documents with the given ids.

Parameters:

  • document_ids (list[str]) – the ids of the documents to delete.

delete_documents_async

python
delete_documents_async(document_ids: list[str]) -> None

Deletes all documents with the given ids.

Parameters:

  • document_ids (list[str]) – the ids of the documents to delete.

delete_all_documents

python
delete_all_documents() -> None

Deletes all documents in the core, leaving the schema in place.

delete_all_documents_async

python
delete_all_documents_async() -> None

Deletes all documents in the core, leaving the schema in place.

delete_by_filter

python
delete_by_filter(filters: dict[str, Any]) -> int

Deletes all documents matching the given filters.

Parameters:

  • filters (dict[str, Any]) – the filters selecting the documents to delete.

Returns:

  • int – the number of documents deleted. The count is taken with a separate query before the delete is issued, so a concurrent write landing in between can make it differ from the number of documents the delete actually removes.

delete_by_filter_async

python
delete_by_filter_async(filters: dict[str, Any]) -> int

Deletes all documents matching the given filters.

Parameters:

  • filters (dict[str, Any]) – the filters selecting the documents to delete.

Returns:

  • int – the number of documents deleted. The count is taken with a separate query before the delete is issued, so a concurrent write landing in between can make it differ from the number of documents the delete actually removes.

update_by_filter

python
update_by_filter(filters: dict[str, Any], meta: dict[str, Any]) -> int

Merges meta into the metadata of every document matching filters.

Matching documents are read, merged and rewritten in full rather than updated in place. A Solr atomic update sets one field at a time, which would leave the previous value behind in another field whenever a metadata value changes Python type, since the type is part of the field name.

Parameters:

  • filters (dict[str, Any]) – the filters selecting the documents to update.
  • meta (dict[str, Any]) – the metadata to merge into each matching document.

Returns:

  • int – the number of documents updated.

update_by_filter_async

python
update_by_filter_async(filters: dict[str, Any], meta: dict[str, Any]) -> int

Merges meta into the metadata of every document matching filters.

Parameters:

  • filters (dict[str, Any]) – the filters selecting the documents to update.
  • meta (dict[str, Any]) – the metadata to merge into each matching document.

Returns:

  • int – the number of documents updated.

get_metadata_fields_info

python
get_metadata_fields_info() -> dict[str, dict[str, str]]

Returns the metadata fields present in the core and their types.

Returns:

  • dict[str, dict[str, str]] – a mapping of metadata field name to a dict with a type key.

get_metadata_fields_info_async

python
get_metadata_fields_info_async() -> dict[str, dict[str, str]]

Returns the metadata fields present in the core and their types.

Returns:

  • dict[str, dict[str, str]] – a mapping of metadata field name to a dict with a type key.

count_unique_metadata_by_filter

python
count_unique_metadata_by_filter(
filters: dict[str, Any], metadata_fields: list[str]
) -> dict[str, int]

Counts the distinct values of each given metadata field among documents matching filters.

Parameters:

  • filters (dict[str, Any]) – the filters restricting which documents are considered.
  • metadata_fields (list[str]) – the metadata fields to count distinct values for.

Returns:

  • dict[str, int] – a mapping of metadata field name to its number of distinct values.

count_unique_metadata_by_filter_async

python
count_unique_metadata_by_filter_async(
filters: dict[str, Any], metadata_fields: list[str]
) -> dict[str, int]

Counts the distinct values of each given metadata field among documents matching filters.

Parameters:

  • filters (dict[str, Any]) – the filters restricting which documents are considered.
  • metadata_fields (list[str]) – the metadata fields to count distinct values for.

Returns:

  • dict[str, int] – a mapping of metadata field name to its number of distinct values.

get_metadata_field_min_max

python
get_metadata_field_min_max(
metadata_field: str,
) -> dict[str, float | int | None]

Returns the minimum and maximum value of a numeric metadata field.

Parameters:

  • metadata_field (str) – the metadata field, with or without a meta. prefix.

Returns:

  • dict[str, float | int | None] – a dict with min and max keys, both None when the field has no numeric values.

get_metadata_field_min_max_async

python
get_metadata_field_min_max_async(
metadata_field: str,
) -> dict[str, float | int | None]

Returns the minimum and maximum value of a numeric metadata field.

Parameters:

  • metadata_field (str) – the metadata field, with or without a meta. prefix.

Returns:

  • dict[str, float | int | None] – a dict with min and max keys, both None when the field has no numeric values.

get_metadata_field_unique_values

python
get_metadata_field_unique_values(
metadata_field: str,
search_term: str | None = None,
from_: int = 0,
size: int = 10,
filters: dict[str, Any] | None = None,
) -> tuple[list[Any], int]

Returns the distinct values of a metadata field, paginated.

Parameters:

  • metadata_field (str) – the metadata field, with or without a meta. prefix.
  • search_term (str | None) – when given, only values containing it (case-insensitively) are returned.
  • from_ (int) – index of the first value to return.
  • size (int) – how many values to return.
  • filters (dict[str, Any] | None) – filters restricting which documents are considered.

Returns:

  • tuple[list[Any], int] – a (values, total_count) pair, where total_count counts all matching values.

get_metadata_field_unique_values_async

python
get_metadata_field_unique_values_async(
metadata_field: str,
search_term: str | None = None,
from_: int = 0,
size: int = 10,
filters: dict[str, Any] | None = None,
) -> tuple[list[Any], int]

Returns the distinct values of a metadata field, paginated.

Parameters:

  • metadata_field (str) – the metadata field, with or without a meta. prefix.
  • search_term (str | None) – when given, only values containing it (case-insensitively) are returned.
  • from_ (int) – index of the first value to return.
  • size (int) – how many values to return.
  • filters (dict[str, Any] | None) – filters restricting which documents are considered.

Returns:

  • tuple[list[Any], int] – a (values, total_count) pair, where total_count counts all matching values.

haystack_integrations.document_stores.solr.filters

Translation of Haystack filters into Solr filter query (fq) clauses.

escape_query_chars

python
escape_query_chars(value: str) -> str

Escape the Lucene syntax characters in value.

Parameters:

  • value (str) – the raw string.

Returns:

  • str – the string with every syntax character and every whitespace run backslash-escaped.

normalize_filters

python
normalize_filters(filters: dict[str, Any]) -> str

Convert Haystack filters into a single Solr filter query clause.

Parameters:

  • filters (dict[str, Any]) – the filters to convert, in Haystack's comparison/logic dictionary form.

Returns:

  • str – a clause suitable for Solr's fq parameter or for a delete-by-query.

Raises:

  • FilterError – if filters is malformed or uses an unsupported operator or value type.

haystack_integrations.document_stores.solr.schema

Mapping between Haystack Documents and Solr documents.

Solr is strongly typed: a field's type is fixed the first time the field is created and a value of the wrong type is rejected. Haystack metadata, on the other hand, is an arbitrary dict[str, Any] whose value types are only known at write time. To reconcile the two, every metadata entry is stored in a Solr field whose name encodes the Python type of the value:

meta.page = "100" -> meta_s_page = "100" (string)
meta.page = 100 -> meta_l_page = 100 (plong)

The type code lives in the prefix rather than the suffix because Solr dynamic field patterns accept only a leading or a trailing wildcard - meta_*_s is not a legal pattern, while meta_s_* is.

Encoding the type in the field name buys two properties that a single JSON blob or Solr's schemaless type inference cannot provide:

  • metadata round-trips with its Python type intact, so {"page": "100"} never comes back as {"page": 100};
  • values that merely share a string form stay distinct, so the int 1, the str "1", the float 1.0 and the bool True occupy four different fields and are reported as four distinct values.

type_code_for_value

python
type_code_for_value(value: Any) -> str

Return the type code under which value is stored.

Homogeneous lists of scalars use the multi-valued code for their element type. Everything else - dicts, mixed lists, nested structures - falls back to a JSON-encoded string.

Parameters:

  • value (Any) – the metadata value to classify.

Returns:

  • str – one of the codes in ALL_TYPE_CODES.

meta_field_name

python
meta_field_name(key: str, type_code: str) -> str

Build the Solr field name holding metadata key at type_code.

Parameters:

  • key (str) – the Haystack metadata key.
  • type_code (str) – one of the codes in ALL_TYPE_CODES.

Returns:

  • str – the Solr field name, e.g. meta_s_page.

parse_meta_field_name

python
parse_meta_field_name(field: str) -> tuple[str, str] | None

Invert meta_field_name.

Parameters:

  • field (str) – a Solr field name.

Returns:

  • tuple[str, str] | None – a (type_code, key) pair, or None if field is not a metadata field. Type codes contain no underscore, so a single split is unambiguous even when the key does.

validate_meta_keys

python
validate_meta_keys(meta: dict[str, Any]) -> None

Reject metadata keys that cannot be expressed as a Solr field name.

Parameters:

  • meta (dict[str, Any]) – the metadata of a single document.

Raises:

  • ValueError – if any key contains a character outside [A-Za-z0-9_]. Silently rewriting such keys would let two distinct keys collide, so the write is refused instead.

document_to_solr

python
document_to_solr(document: Document) -> dict[str, Any]

Convert a Haystack Document into a Solr document.

Parameters:

  • document (Document) – the document to convert.

Returns:

  • dict[str, Any] – a JSON-serializable dict ready to be posted to Solr's update handler.

Raises:

  • ValueError – if a metadata key cannot be expressed as a Solr field name.

solr_to_document

python
solr_to_document(
solr_document: dict[str, Any], *, score: float | None = None
) -> Document

Convert a Solr document back into a Haystack Document.

Parameters:

  • solr_document (dict[str, Any]) – a single entry from a Solr query response.
  • score (float | None) – the relevance score to attach, when the document came from a retrieval query.

Returns:

  • Document – the reconstructed document.

vector_field_type_name

python
vector_field_type_name(embedding_dim: int) -> str

Return the name of the DenseVectorField type backing embeddings of embedding_dim dimensions.

Parameters:

  • embedding_dim (int) – the embedding dimension.

Returns:

  • str – the Solr field type name.

schema_payload

python
schema_payload(
*,
embedding_dim: int,
similarity_function: str,
existing_field_types: set[str],
existing_fields: set[str],
existing_dynamic_fields: set[str],
vector_field_type_params: dict[str, Any] | None = None
) -> dict[str, Any]

Build an idempotent Schema API payload creating only what the core is missing.

Parameters:

  • embedding_dim (int) – dimension of the DenseVectorField backing embeddings.
  • similarity_function (str) – cosine, dot_product or euclidean.
  • existing_field_types (set[str]) – field type names already defined in the core.
  • existing_fields (set[str]) – field names already defined in the core.
  • existing_dynamic_fields (set[str]) – dynamic field patterns already defined in the core.
  • vector_field_type_params (dict[str, Any] | None) – extra attributes for the vector field type, for example {"hnswM": 32} on Solr 10 or {"hnswMaxConnections": 32} on Solr 9. Left unset by default so that one payload is valid on both major versions, which renamed these attributes.

Returns:

  • dict[str, Any] – the Schema API payload. Empty when the core already has everything.