Skip to content

Conversation

@vishwarajanand
Copy link
Owner

@vishwarajanand vishwarajanand commented May 19, 2025

Adds hybrid search in async vector store.

Key features:

  • Insert (actually an upsert) a document with TSV column
  • Search when hybrid config is provided, in both the following cases:
    • With TSV column
    • Without TSV column
Test Log for test_async_pg_vectorstore_search.py

(venv311) (base) ➜ langchain-postgres git:(hybrid_search_3) ✗ python -m pytest -vvv tests/unit_tests/v2/test_async_pg_vectorstore_search.py
/usr/local/google/home/vishwarajanand/github/langchain-postgres/venv311/lib/python3.11/site-packages/pytest_asyncio/plugin.py:217: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session"

warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
====================================================== test session starts =======================================================
platform linux -- Python 3.11.12, pytest-8.3.5, pluggy-1.6.0 -- /usr/local/google/home/vishwarajanand/github/langchain-postgres/venv311/bin/python
cachedir: .pytest_cache
rootdir: /usr/local/google/home/vishwarajanand/github/langchain-postgres
configfile: pyproject.toml
plugins: anyio-4.9.0, timeout-2.4.0, asyncio-0.26.0, langsmith-0.3.42
timeout: 30.0s
timeout method: signal
timeout func_only: False
asyncio: mode=Mode.AUTO, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 66 items

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_asimilarity_search_score
PASSED [ 1%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_asimilarity_search_by_vector PASSED [ 3%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_simihold_cosine PASSED [ 4%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_with_relevance_scores_threshold_euclidean PASSED [ 6%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_amax_marginal_relevance_search_vector PASSED [ 7%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_amax_marginal_relevance_search_vector_score PASSED [ 9%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_score PASSED [ 10%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_by_vector PASSED [ 12%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_max_marginal_relevance_search_vector PASSED [ 13%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_max_marginal_relevance_search_vector_score PASSED [ 15%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_aget_by_ids PASSED [ 16%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_aget_by_ids_custom_vs PASSED [ 18%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_get_by_ids PASSED [ 19%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter0-expected_ids0] PASSED [ 21%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter1-expected_ids1] PASSED [ 22%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter2-expected_ids2] PASSED [ 24%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter3-expected_ids3] PASSED [ 25%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter4-expected_ids4] PASSED [ 27%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter5-expected_ids5] PASSED [ 28%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter6-expected_ids6] PASSED [ 30%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter7-expected_ids7] PASSED [ 31%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter8-expected_ids8] PASSED [ 33%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter9-expected_ids9] PASSED [ 34%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter10-expected_ids10] PASSED [ 36%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter11-expected_ids11] PASSED [ 37%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter12-expected_ids12] PASSED [ 39%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter13-expected_ids13] PASSED [ 40%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter14-expected_ids14] PASSED [ 42%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter15-expected_ids15] PASSED [ 43%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter16-expected_ids16] PASSED [ 45%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter17-expected_ids17] PASSED [ 46%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter18-expected_ids18] PASSED [ 48%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter19-expected_ids19] PASSED [ 50%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter20-expected_ids20] PASSED [ 51%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter21-expected_ids21] PASSED [ 53%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter22-expected_ids22] PASSED [ 54%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter23-expected_ids23] PASSED [ 56%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter24-expected_ids24] PASSED [ 57%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter25-expected_ids25] PASSED [ 59%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter26-expected_ids26] PASSED [ 60%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter27-expected_ids27] PASSED [ 62%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter28-expected_ids28] PASSED [ 63%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter29-expected_ids29] PASSED [ 65%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter30-expected_ids30] PASSED [ 66%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter31-expected_ids31] PASSED [ 68%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter32-expected_ids32] PASSED [ 69%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter33-expected_ids33] PASSED [ 71%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter34-expected_ids34] PASSED [ 72%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter35-expected_ids35] PASSED [ 74%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter36-expected_ids36] PASSED [ 75%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter37-expected_ids37] PASSED [ 77%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter38-expected_ids38] PASSED [ 78%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter39-expected_ids39] PASSED [ 80%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter40-expected_ids40] PASSED [ 81%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter41-expected_ids41] PASSED [ 83%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_asimilarity_hybrid_search PASSED [ 84%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_asimilarity_hybrid_search_rrk PASSED [ 86%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_weighted_sum_default PASSED [ 87%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_weighted_sum_vector_bias PASSED [ 89%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_weighted_sum_fts_bias PASSED [ 90%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_reciprocal_rank_fusion PASSED [ 92%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_explicit_fts_query PASSED [ 93%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_with_filter PASSED [ 95%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_fts_empty_results PASSED [ 96%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_vector_empty_results_effectively PASSED [ 98%]
tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_without_tsv_column PASSED [100%]

=================================== warnings summary ====================================
venv311/lib/python3.11/site-packages/pytest_asyncio/plugin.py:1140: 25 warnings
tests/unit_tests/v2/test_async_pg_vectorstore_search.py: 66 warnings
/usr/local/google/home/vishwarajanand/github/langchain-postgres/venv311/lib/python3.11/site-packages/pytest_asyncio/plugin.py:1140: PytestDeprecationWarning: The "scope" keyword argument to the asyncio marker has been deprecated. Please use the "loop_scope" argument instead.

warnings.warn(PytestDeprecationWarning(_MARKER_SCOPE_KWARG_DEPRECATION_WARNING))

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_with_relevance_scores_threshold_cosine
/usr/local/google/home/vishwarajanand/github/langchain-postgres/tests/unit_tests/v2/test_async_pg_vectorstore_search.py:237: UserWarning: Relevance scores must be between 0 and 1, got [(Document(id='454cf0d9-575b-4ab2-ba80-13308f45775d', metadata={}, page_content='foo'), 1.0), (Document(id='bd0da7c2-0df9-4776-81d7-8da8b15f8312', metadata={}, page_content='baz'), 0.033868862789414256), (Document(id='5fc7ac72-006e-4c91-9a49-3811d27cc415', metadata={}, page_content='bar'), -0.016848503262605563), (Document(id='f4fbc5d1-8f86-44fb-a03b-1f90491918a6', metadata={}, page_content='boo'), -0.02413091857518168)]
results = await vs.asimilarity_search_with_relevance_scores(

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_with_relevance_scores_threshold_cosine
/usr/local/google/home/vishwarajanand/github/langchain-postgres/tests/unit_tests/v2/test_async_pg_vectorstore_search.py:245: UserWarning: Relevance scores must be between 0 and 1, got [(Document(id='454cf0d9-575b-4ab2-ba80-13308f45775d', metadata={}, page_content='foo'), 1.0), (Document(id='bd0da7c2-0df9-4776-81d7-8da8b15f8312', metadata={}, page_content='baz'), 0.033868862789414256), (Document(id='5fc7ac72-006e-4c91-9a49-3811d27cc415', metadata={}, page_content='bar'), -0.016848503262605563), (Document(id='f4fbc5d1-8f86-44fb-a03b-1f90491918a6', metadata={}, page_content='boo'), -0.02413091857518168)]
results = await vs.asimilarity_search_with_relevance_scores(

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_with_relevance_scores_threshold_cosine
/usr/local/google/home/vishwarajanand/github/langchain-postgres/tests/unit_tests/v2/test_async_pg_vectorstore_search.py:251: UserWarning: Relevance scores must be between 0 and 1, got [(Document(id='454cf0d9-575b-4ab2-ba80-13308f45775d', metadata={}, page_content='foo'), 1.0), (Document(id='bd0da7c2-0df9-4776-81d7-8da8b15f8312', metadata={}, page_content='baz'), 0.033868862789414256), (Document(id='5fc7ac72-006e-4c91-9a49-3811d27cc415', metadata={}, page_content='bar'), -0.016848503262605563), (Document(id='f4fbc5d1-8f86-44fb-a03b-1f90491918a6', metadata={}, page_content='boo'), -0.02413091857518168)]
results = await vs.asimilarity_search_with_relevance_scores(

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_with_relevance_scores_threshold_cosine
/usr/local/google/home/vishwarajanand/github/langchain-postgres/tests/unit_tests/v2/test_async_pg_vectorstore_search.py:259: UserWarning: Relevance scores must be between 0 and 1, got [(Document(id='454cf0d9-575b-4ab2-ba80-13308f45775d', metadata={}, page_content='foo'), 1.0), (Document(id='f4fbc5d1-8f86-44fb-a03b-1f90491918a6', metadata={}, page_content='boo'), -26.2829838187594), (Document(id='5fc7ac72-006e-4c91-9a49-3811d27cc415', metadata={}, page_content='bar'), -26.38526981663112), (Document(id='bd0da7c2-0df9-4776-81d7-8da8b15f8312', metadata={}, page_content='baz'), -26.609221358160507)]
results = await vs.asimilarity_search_with_relevance_scores(

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_with_relevance_scores_threshold_euclidean
/usr/local/google/home/vishwarajanand/github/langchain-postgres/tests/unit_tests/v2/test_async_pg_vectorstore_search.py:275: UserWarning: Relevance scores must be between 0 and 1, got [(Document(id='454cf0d9-575b-4ab2-ba80-13308f45775d', metadata={}, page_content='foo'), 1.0), (Document(id='f4fbc5d1-8f86-44fb-a03b-1f90491918a6', metadata={}, page_content='boo'), -26.2829838187594), (Document(id='5fc7ac72-006e-4c91-9a49-3811d27cc415', metadata={}, page_content='bar'), -26.38526981663112), (Document(id='bd0da7c2-0df9-4776-81d7-8da8b15f8312', metadata={}, page_content='baz'), -26.609221358160507)]
results = await vs.asimilarity_search_with_relevance_scores(

tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_get_by_ids
tests/unit_tests/v2/test_async_pg_vectorstore_search.py:355: PytestWarning: The test is marked with '@pytest.mark.asyncio' but it is not an async function. Please remove the asyncio mark. If the test is not marked explicitly, check for global marks applied via 'pytestmark'.
def test_get_by_ids(self, vs: AsyncPGVectorStore) -> None:

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================================== slowest 5 durations ==================================
8.83s call tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_without_tsv_column
8.12s setup tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_asimilarity_search_score
5.14s setup tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_hybrid_search_weighted_sum_default
4.48s setup tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_vectorstore_with_metadata_filters[test_filter0-expected_ids0]
4.48s setup tests/unit_tests/v2/test_async_pg_vectorstore_search.py::TestVectorStoreSearch::test_similarity_search_score
====================== 66 passed, 97 warnings in 98.68s (0:01:38) =======================
(venv311) (base) ➜ langchain-postgres git:(hybrid_search_3) ✗

Test Log for test_async_pg_vectorstore_index.py

(venv311) (base) ➜ langchain-postgres git:(hybrid_search_3) ✗ python -m pytest -vvv tests/unit_tests/v2/test_async_pg_vectorstore_index.py
/usr/local/google/home/vishwarajanand/github/langchain-postgres/venv311/lib/python3.11/site-packages/pytest_asyncio/plugin.py:217: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session"

warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
================== test session starts ==================
platform linux -- Python 3.11.12, pytest-8.3.5, pluggy-1.6.0 -- /usr/local/google/home/vishwarajanand/github/langchain-postgres/venv311/bin/python
cachedir: .pytest_cache
rootdir: /usr/local/google/home/vishwarajanand/github/langchain-postgres
configfile: pyproject.toml
plugins: anyio-4.9.0, timeout-2.4.0, asyncio-0.26.0, langsmith-0.3.42
timeout: 30.0s
timeout method: signal
timeout func_only: False
asyncio: mode=Mode.AUTO, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 9 items

tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_apply_default_name_vector_index PASSED [ 11%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_vector_index PASSED [ 22%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_vector_index_non_hybrid_search_vs PASSED [ 33%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_hybrid_search_index_table_without_tsv_column PASSED [ 44%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_hybrid_search_index_table_with_tsv_column PASSED [ 55%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_areindex PASSED [ 66%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_dropindex PASSED [ 77%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_vector_index_ivfflat PASSED [ 88%]
tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_is_valid_index PASSED [100%]

=================== warnings summary ====================
venv311/lib/python3.11/site-packages/pytest_asyncio/plugin.py:1140: 9 warnings
tests/unit_tests/v2/test_async_pg_vectorstore_index.py: 9 warnings
/usr/local/google/home/vishwarajanand/github/langchain-postgres/venv311/lib/python3.11/site-packages/pytest_asyncio/plugin.py:1140: PytestDeprecationWarning: The "scope" keyword argument to the asyncio marker has been deprecated. Please use the "loop_scope" argument instead.

warnings.warn(PytestDeprecationWarning(_MARKER_SCOPE_KWARG_DEPRECATION_WARNING))

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
================== slowest 5 durations ==================
10.76s call tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_apply_default_name_vector_index
6.43s call tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_hybrid_search_index_table_with_tsv_column
4.51s setup tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_vector_index
4.04s call tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_areindex
3.86s call tests/unit_tests/v2/test_async_pg_vectorstore_index.py::TestIndex::test_aapply_hybrid_search_index_table_without_tsv_column
============ 9 passed, 18 warnings in 39.76s ============
(venv311) (base) ➜ langchain-postgres git:(hybrid_search_3) ✗

Copy link

@dishaprakash dishaprakash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

if hybrid_search_config.tsv_column
else content_column + "_tsv"
)
hybrid_search_config.tsv_column = tsv_column_name

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we only update the name if the column exists, then we don't have to manage the separate boolean?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you propose makes more sense, I'll change the code accordingly:

The proposed behavior needs some clarity in following cases:

Case Current Behavior Proposed behavior
No hybrid_search_config provided Traditional Search Same
User provided hybrid_search_config.tsv_column is empty HS will set column name to content_column + '_tsv' Check for column existence
Store hybrid_search_column_exists along with column name
User provided a valid hybrid_search_config.tsv_column HS will check for column existence
Store hybrid_search_column_exists along with column name
Check for column existence
Reset column name to empty if column does not exist.

@averikitsch
Copy link

Can you add some documentation the default use case and how to customize to https://github.com/langchain-ai/langchain-postgres/blob/main/examples/pg_vectorstore_how_to.ipynb?

@vishwarajanand vishwarajanand marked this pull request as ready for review June 3, 2025 06:42
@vishwarajanand vishwarajanand merged commit 076f0cb into hybrid_search_2 Jun 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants