def test_filter_conditions():
    """Test AND, OR, and NOT filter conditions."""
    from llama_index.core.vector_stores.types import (
        MetadataFilter,
        MetadataFilters,
        FilterCondition,
        FilterOperator,
    )

    # Create a mock Qdrant client
    mock_client = MagicMock(spec=QdrantClient)
    vector_store = QdrantVectorStore(
        collection_name="test_collection",
        client=mock_client,
    )

    # Test AND condition
    and_filter = MetadataFilters(
        filters=[
            MetadataFilter(key="category", value="books", operator=FilterOperator.EQ),
            MetadataFilter(key="price", value=10, operator=FilterOperator.GT),
        ],
        condition=FilterCondition.AND,
    )
    filter_and = vector_store._build_subfilter(and_filter)
    assert filter_and.must is not None
    assert len(filter_and.must) == 2
    assert filter_and.must[0].key == "category"
    assert filter_and.must[0].match.value == "books"
    assert filter_and.must[1].key == "price"
    assert filter_and.must[1].range.gt == 10

    # Test OR condition
    or_filter = MetadataFilters(
        filters=[
            MetadataFilter(key="category", value="books", operator=FilterOperator.EQ),
            MetadataFilter(
                key="category", value="electronics", operator=FilterOperator.EQ
            ),
        ],
        condition=FilterCondition.OR,
    )
    filter_or = vector_store._build_subfilter(or_filter)
    assert filter_or.should is not None
    assert len(filter_or.should) == 2
    assert filter_or.should[0].key == "category"
    assert filter_or.should[0].match.value == "books"
    assert filter_or.should[1].key == "category"
    assert filter_or.should[1].match.value == "electronics"

    # Test NOT condition
    not_filter = MetadataFilters(
        filters=[
            MetadataFilter(key="category", value="books", operator=FilterOperator.EQ),
        ],
        condition="not",
    )
    filter_not = vector_store._build_subfilter(not_filter)
    assert filter_not.must_not is not None
    assert len(filter_not.must_not) == 1
    assert filter_not.must_not[0].key == "category"
    assert filter_not.must_not[0].match.value == "books"

    # Test AND with NOT condition
    and_not_filter = MetadataFilters(
        filters=[
            MetadataFilter(key="category", value="books", operator=FilterOperator.EQ),
            MetadataFilters(
                filters=[
                    MetadataFilter(key="price", value=50, operator=FilterOperator.EQ),
                ],
                condition="not",
            ),
        ],
        condition=FilterCondition.AND,
    )
    filter_and_not = vector_store._build_subfilter(and_not_filter)
    assert filter_and_not.must is not None
    assert (
        len(filter_and_not.must) == 2
    )  # One for category and one for the nested filter
    assert filter_and_not.must[0].key == "category"
    assert filter_and_not.must[0].match.value == "books"
    # The second must element is a Filter object with must_not condition
    assert isinstance(filter_and_not.must[1], Filter)
    assert filter_and_not.must[1].must_not is not None
    assert len(filter_and_not.must[1].must_not) == 1
    assert filter_and_not.must[1].must_not[0].key == "price"
    assert filter_and_not.must[1].must_not[0].match.value == 50
Test AND, OR, and NOT filter conditions.
llama-index-integrations/vector_stores/llama-index-vector-stores-qdrant/tests/test_vector_stores_qdrant.py