From 78e76eca036c8e1f736d9ccdda97eb57b093f149 Mon Sep 17 00:00:00 2001 From: ZB-io Date: Tue, 18 Nov 2025 13:59:38 +0530 Subject: [PATCH] Unit test generated by RoostGPT Using AI Model eu.anthropic.claude-sonnet-4-20250514-v1:0 --- pom.xml | 2077 ++++++++--------- ...erExpressionConverterDoExpressionTest.java | 315 +++ ...erExpressionConverterDoExpressionTest.java | 254 ++ 3 files changed, 1597 insertions(+), 1049 deletions(-) create mode 100644 src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java create mode 100644 vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java diff --git a/pom.xml b/pom.xml index b4f16c0a912..32d4138af8a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,4 @@ + - - - 4.0.0 - - org.springframework.ai - spring-ai-parent - 1.1.1-SNAPSHOT - - pom - https://github.com/spring-projects/spring-ai - - Spring AI Parent - Building AI applications with Spring Boot - - - spring-ai-docs - spring-ai-bom - spring-ai-commons - spring-ai-template-st - spring-ai-client-chat - spring-ai-model - spring-ai-test - spring-ai-vector-store - spring-ai-rag - advisors/spring-ai-advisors-vector-store - - memory/repository/spring-ai-model-chat-memory-repository-cassandra - memory/repository/spring-ai-model-chat-memory-repository-cosmos-db - memory/repository/spring-ai-model-chat-memory-repository-jdbc - memory/repository/spring-ai-model-chat-memory-repository-mongodb - memory/repository/spring-ai-model-chat-memory-repository-neo4j - - - - spring-ai-retry - spring-ai-spring-boot-docker-compose - spring-ai-spring-boot-testcontainers - spring-ai-spring-cloud-bindings - - document-readers/jsoup-reader - document-readers/markdown-reader - document-readers/pdf-reader - document-readers/tika-reader - - vector-stores/spring-ai-azure-cosmos-db-store - vector-stores/spring-ai-azure-store - vector-stores/spring-ai-cassandra-store - vector-stores/spring-ai-chroma-store - vector-stores/spring-ai-coherence-store - vector-stores/spring-ai-couchbase-store - vector-stores/spring-ai-elasticsearch-store - vector-stores/spring-ai-gemfire-store - vector-stores/spring-ai-hanadb-store - vector-stores/spring-ai-mariadb-store - vector-stores/spring-ai-milvus-store - vector-stores/spring-ai-mongodb-atlas-store - vector-stores/spring-ai-neo4j-store - vector-stores/spring-ai-opensearch-store - vector-stores/spring-ai-oracle-store - vector-stores/spring-ai-pgvector-store - vector-stores/spring-ai-pinecone-store - vector-stores/spring-ai-qdrant-store - vector-stores/spring-ai-redis-store - vector-stores/spring-ai-typesense-store - vector-stores/spring-ai-weaviate-store - - - auto-configurations/common/spring-ai-autoconfigure-retry - - auto-configurations/models/tool/spring-ai-autoconfigure-model-tool - - auto-configurations/models/chat/client/spring-ai-autoconfigure-model-chat-client - - auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory - auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-cassandra - auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-cosmos-db - auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc - auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-mongodb - auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-neo4j - - auto-configurations/models/chat/observation/spring-ai-autoconfigure-model-chat-observation - - auto-configurations/models/embedding/observation/spring-ai-autoconfigure-model-embedding-observation - auto-configurations/models/image/observation/spring-ai-autoconfigure-model-image-observation - - auto-configurations/models/spring-ai-autoconfigure-model-anthropic - auto-configurations/models/spring-ai-autoconfigure-model-azure-openai - auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai - auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs - auto-configurations/models/spring-ai-autoconfigure-model-huggingface - auto-configurations/models/spring-ai-autoconfigure-model-openai - auto-configurations/models/spring-ai-autoconfigure-model-minimax - auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai - auto-configurations/models/spring-ai-autoconfigure-model-oci-genai - auto-configurations/models/spring-ai-autoconfigure-model-ollama - - auto-configurations/models/spring-ai-autoconfigure-model-postgresml-embedding - auto-configurations/models/spring-ai-autoconfigure-model-stability-ai - auto-configurations/models/spring-ai-autoconfigure-model-transformers - auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai - auto-configurations/models/spring-ai-autoconfigure-model-google-genai - auto-configurations/models/spring-ai-autoconfigure-model-zhipuai - auto-configurations/models/spring-ai-autoconfigure-model-deepseek - - auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common - auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient - auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux - - auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common - auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webmvc - auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webflux - - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-azure - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-azure-cosmos-db - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-cassandra - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-gemfire - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-milvus - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mongodb-atlas - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-neo4j - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-opensearch - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-observation - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-oracle - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pinecone - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-qdrant - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-redis - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-typesense - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate - auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector - - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-aws-opensearch - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-azure - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-azure-cosmos-db - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-cassandra - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-chroma - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-couchbase - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-elasticsearch - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-gemfire - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-mariadb - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-milvus - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-mongodb-atlas - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-neo4j - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-opensearch - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-oracle - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-pgvector - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-pinecone - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-qdrant - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-redis - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-typesense - spring-ai-spring-boot-starters/spring-ai-starter-vector-store-weaviate - - models/spring-ai-anthropic - models/spring-ai-azure-openai - models/spring-ai-bedrock - models/spring-ai-bedrock-converse - models/spring-ai-elevenlabs - models/spring-ai-huggingface - models/spring-ai-minimax - models/spring-ai-mistral-ai - models/spring-ai-oci-genai - models/spring-ai-ollama - models/spring-ai-openai - models/spring-ai-postgresml - models/spring-ai-stability-ai - models/spring-ai-transformers - models/spring-ai-vertex-ai-embedding - models/spring-ai-vertex-ai-gemini - models/spring-ai-google-genai - models/spring-ai-google-genai-embedding - models/spring-ai-zhipuai - models/spring-ai-deepseek - - spring-ai-spring-boot-starters/spring-ai-starter-model-anthropic - spring-ai-spring-boot-starters/spring-ai-starter-model-azure-openai - spring-ai-spring-boot-starters/spring-ai-starter-model-bedrock - spring-ai-spring-boot-starters/spring-ai-starter-model-bedrock-converse - spring-ai-spring-boot-starters/spring-ai-starter-model-google-genai - spring-ai-spring-boot-starters/spring-ai-starter-model-google-genai-embedding - spring-ai-spring-boot-starters/spring-ai-starter-model-elevenlabs - spring-ai-spring-boot-starters/spring-ai-starter-model-huggingface - spring-ai-spring-boot-starters/spring-ai-starter-model-minimax - spring-ai-spring-boot-starters/spring-ai-starter-model-mistral-ai - spring-ai-spring-boot-starters/spring-ai-starter-model-oci-genai - spring-ai-spring-boot-starters/spring-ai-starter-model-ollama - spring-ai-spring-boot-starters/spring-ai-starter-model-openai - spring-ai-spring-boot-starters/spring-ai-starter-model-postgresml-embedding - spring-ai-spring-boot-starters/spring-ai-starter-model-stability-ai - spring-ai-spring-boot-starters/spring-ai-starter-model-transformers - spring-ai-spring-boot-starters/spring-ai-starter-model-vertex-ai-embedding - spring-ai-spring-boot-starters/spring-ai-starter-model-vertex-ai-gemini - spring-ai-spring-boot-starters/spring-ai-starter-model-zhipuai - spring-ai-spring-boot-starters/spring-ai-starter-model-deepseek - - spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory - spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-cassandra - spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-jdbc - spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-mongodb - spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-neo4j - - spring-ai-spring-boot-starters/spring-ai-starter-mcp-client - spring-ai-spring-boot-starters/spring-ai-starter-mcp-server - spring-ai-spring-boot-starters/spring-ai-starter-mcp-client-webflux - spring-ai-spring-boot-starters/spring-ai-starter-mcp-server-webflux - spring-ai-spring-boot-starters/spring-ai-starter-mcp-server-webmvc - - spring-ai-integration-tests - - mcp/common - mcp/mcp-annotations-spring - - - - VMware Inc. - https://spring.io - - - https://github.com/spring-projects/spring-ai - git://github.com/spring-projects/spring-ai.git - git@github.com:spring-projects/spring-ai.git - - - Github Issues - https://github.com/spring-projects/spring-ai/issues - - - Github Actions - https://github.com/spring-projects/spring-ai/actions - - - - spring-snapshots - https://repo.spring.io/libs-snapshot-local - - false - - - - - - Apache 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - UTF-8 - UTF-8 - 17 - ${java.version} - ${java.version} - ${java.version} - - - 3.5.7 - 4.3.4 - 1.0.0-beta.16 - 1.1.0 - 1.9.25 - - - 2.36.3 - 2.36.3 - - 0.32.0 - 1.19.2 - 3.63.1 - 26.60.0 - 1.17.0 - 9.20.0 - 4.38.0 - 2.2.30 - 1.13.13 - 2.0.3 - - 1.21.2 - - - 3.25.8 - - - 3.0.5 - 0.1.6 - 2.20.11 - 24.09 - 2.5.8 - 2.3.0 - 1.20.4 - - 4.0.1 - 4.29.3 - - 2.0.46 - 1.55.3 - 1.5.0 - 1.15.4 - 11.7.6 - 5.22.0 - 8.18.1 - 5.2.0 - 1.13.0 - 1.3.0 - 2.23.0 - 42.7.7 - 3.5.3 - 9.2.0 - 0.22.0 - - 3.9.1 - 2024.5.1 - - - 4.12.0 - 4.1.0 - - - 0.16.0 - 0.7.0 - - - 4.13.1 - 3.11.0 - 3.1.2 - 3.5.2 - 3.5.0 - 3.3.0 - 0.8.10 - 1.5.0 - 3.1.1 - 2.2.3 - 3.7.0 - 3.5.0 - 4.0.0-M13 - 3.4.5 - 3.3.0 - 0.0.43 - 1.0.0-alpha.5 - 0.0.4 - 3.5.0 - true - true - 9.3 - 0.0.43 - 3.2.8 - - false - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${maven-checkstyle-plugin.version} - - - com.puppycrawl.tools - checkstyle - ${puppycrawl-tools-checkstyle.version} - - - io.spring.javaformat - spring-javaformat-checkstyle - ${spring-javaformat-checkstyle.version} - - - - - checkstyle-validation - validate - true - - ${disable.checks} - src/checkstyle/checkstyle.xml - src/checkstyle/checkstyle-header.txt - true - + + 4.0.0 + org.springframework.ai + spring-ai-parent + 1.1.1-SNAPSHOT + pom + https://github.com/spring-projects/spring-ai + Spring AI Parent + Building AI applications with Spring Boot + + spring-ai-docs + spring-ai-bom + spring-ai-commons + spring-ai-template-st + spring-ai-client-chat + spring-ai-model + spring-ai-test + spring-ai-vector-store + spring-ai-rag + advisors/spring-ai-advisors-vector-store + memory/repository/spring-ai-model-chat-memory-repository-cassandra + memory/repository/spring-ai-model-chat-memory-repository-cosmos-db + memory/repository/spring-ai-model-chat-memory-repository-jdbc + memory/repository/spring-ai-model-chat-memory-repository-mongodb + memory/repository/spring-ai-model-chat-memory-repository-neo4j + spring-ai-retry + spring-ai-spring-boot-docker-compose + spring-ai-spring-boot-testcontainers + spring-ai-spring-cloud-bindings + document-readers/jsoup-reader + document-readers/markdown-reader + document-readers/pdf-reader + document-readers/tika-reader + vector-stores/spring-ai-azure-cosmos-db-store + vector-stores/spring-ai-azure-store + vector-stores/spring-ai-cassandra-store + vector-stores/spring-ai-chroma-store + vector-stores/spring-ai-coherence-store + vector-stores/spring-ai-couchbase-store + vector-stores/spring-ai-elasticsearch-store + vector-stores/spring-ai-gemfire-store + vector-stores/spring-ai-hanadb-store + vector-stores/spring-ai-mariadb-store + vector-stores/spring-ai-milvus-store + vector-stores/spring-ai-mongodb-atlas-store + vector-stores/spring-ai-neo4j-store + vector-stores/spring-ai-opensearch-store + vector-stores/spring-ai-oracle-store + vector-stores/spring-ai-pgvector-store + vector-stores/spring-ai-pinecone-store + vector-stores/spring-ai-qdrant-store + vector-stores/spring-ai-redis-store + vector-stores/spring-ai-typesense-store + vector-stores/spring-ai-weaviate-store + auto-configurations/common/spring-ai-autoconfigure-retry + auto-configurations/models/tool/spring-ai-autoconfigure-model-tool + auto-configurations/models/chat/client/spring-ai-autoconfigure-model-chat-client + auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory + auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-cassandra + auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-cosmos-db + auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc + auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-mongodb + auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-neo4j + auto-configurations/models/chat/observation/spring-ai-autoconfigure-model-chat-observation + auto-configurations/models/embedding/observation/spring-ai-autoconfigure-model-embedding-observation + auto-configurations/models/image/observation/spring-ai-autoconfigure-model-image-observation + auto-configurations/models/spring-ai-autoconfigure-model-anthropic + auto-configurations/models/spring-ai-autoconfigure-model-azure-openai + auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai + auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs + auto-configurations/models/spring-ai-autoconfigure-model-huggingface + auto-configurations/models/spring-ai-autoconfigure-model-openai + auto-configurations/models/spring-ai-autoconfigure-model-minimax + auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai + auto-configurations/models/spring-ai-autoconfigure-model-oci-genai + auto-configurations/models/spring-ai-autoconfigure-model-ollama + auto-configurations/models/spring-ai-autoconfigure-model-postgresml-embedding + auto-configurations/models/spring-ai-autoconfigure-model-stability-ai + auto-configurations/models/spring-ai-autoconfigure-model-transformers + auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai + auto-configurations/models/spring-ai-autoconfigure-model-google-genai + auto-configurations/models/spring-ai-autoconfigure-model-zhipuai + auto-configurations/models/spring-ai-autoconfigure-model-deepseek + auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common + auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient + auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux + auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common + auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webmvc + auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webflux + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-azure + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-azure-cosmos-db + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-cassandra + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-gemfire + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-milvus + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mongodb-atlas + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-neo4j + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-opensearch + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-observation + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-oracle + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pinecone + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-qdrant + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-redis + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-typesense + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate + auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-aws-opensearch + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-azure + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-azure-cosmos-db + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-cassandra + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-chroma + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-couchbase + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-elasticsearch + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-gemfire + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-mariadb + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-milvus + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-mongodb-atlas + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-neo4j + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-opensearch + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-oracle + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-pgvector + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-pinecone + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-qdrant + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-redis + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-typesense + spring-ai-spring-boot-starters/spring-ai-starter-vector-store-weaviate + models/spring-ai-anthropic + models/spring-ai-azure-openai + models/spring-ai-bedrock + models/spring-ai-bedrock-converse + models/spring-ai-elevenlabs + models/spring-ai-huggingface + models/spring-ai-minimax + models/spring-ai-mistral-ai + models/spring-ai-oci-genai + models/spring-ai-ollama + models/spring-ai-openai + models/spring-ai-postgresml + models/spring-ai-stability-ai + models/spring-ai-transformers + models/spring-ai-vertex-ai-embedding + models/spring-ai-vertex-ai-gemini + models/spring-ai-google-genai + models/spring-ai-google-genai-embedding + models/spring-ai-zhipuai + models/spring-ai-deepseek + spring-ai-spring-boot-starters/spring-ai-starter-model-anthropic + spring-ai-spring-boot-starters/spring-ai-starter-model-azure-openai + spring-ai-spring-boot-starters/spring-ai-starter-model-bedrock + spring-ai-spring-boot-starters/spring-ai-starter-model-bedrock-converse + spring-ai-spring-boot-starters/spring-ai-starter-model-google-genai + spring-ai-spring-boot-starters/spring-ai-starter-model-google-genai-embedding + spring-ai-spring-boot-starters/spring-ai-starter-model-elevenlabs + spring-ai-spring-boot-starters/spring-ai-starter-model-huggingface + spring-ai-spring-boot-starters/spring-ai-starter-model-minimax + spring-ai-spring-boot-starters/spring-ai-starter-model-mistral-ai + spring-ai-spring-boot-starters/spring-ai-starter-model-oci-genai + spring-ai-spring-boot-starters/spring-ai-starter-model-ollama + spring-ai-spring-boot-starters/spring-ai-starter-model-openai + spring-ai-spring-boot-starters/spring-ai-starter-model-postgresml-embedding + spring-ai-spring-boot-starters/spring-ai-starter-model-stability-ai + spring-ai-spring-boot-starters/spring-ai-starter-model-transformers + spring-ai-spring-boot-starters/spring-ai-starter-model-vertex-ai-embedding + spring-ai-spring-boot-starters/spring-ai-starter-model-vertex-ai-gemini + spring-ai-spring-boot-starters/spring-ai-starter-model-zhipuai + spring-ai-spring-boot-starters/spring-ai-starter-model-deepseek + spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory + spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-cassandra + spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-jdbc + spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-mongodb + spring-ai-spring-boot-starters/spring-ai-starter-model-chat-memory-repository-neo4j + spring-ai-spring-boot-starters/spring-ai-starter-mcp-client + spring-ai-spring-boot-starters/spring-ai-starter-mcp-server + spring-ai-spring-boot-starters/spring-ai-starter-mcp-client-webflux + spring-ai-spring-boot-starters/spring-ai-starter-mcp-server-webflux + spring-ai-spring-boot-starters/spring-ai-starter-mcp-server-webmvc + spring-ai-integration-tests + mcp/common + mcp/mcp-annotations-spring + + + VMware Inc. + https://spring.io + + + https://github.com/spring-projects/spring-ai + git://github.com/spring-projects/spring-ai.git + git@github.com:spring-projects/spring-ai.git + + + Github Issues + https://github.com/spring-projects/spring-ai/issues + + + Github Actions + https://github.com/spring-projects/spring-ai/actions + + + + spring-snapshots + https://repo.spring.io/libs-snapshot-local + + false + + + + + + Apache 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + UTF-8 + UTF-8 + 17 + ${java.version} + ${java.version} + ${java.version} + + 3.5.7 + 4.3.4 + 1.0.0-beta.16 + 1.1.0 + 1.9.25 + + 2.36.3 + 2.36.3 + 0.32.0 + 1.19.2 + 3.63.1 + 26.60.0 + 1.17.0 + 9.20.0 + 4.38.0 + 2.2.30 + 1.13.13 + 2.0.3 + 1.21.2 + + 3.25.8 + + 3.0.5 + 0.1.6 + 2.20.11 + 24.09 + 2.5.8 + 2.3.0 + 1.20.4 + 4.0.1 + 4.29.3 + 2.0.46 + 1.55.3 + 1.5.0 + 1.15.4 + 11.7.6 + 5.22.0 + 8.18.1 + 5.2.0 + 1.13.0 + 1.3.0 + 2.23.0 + 42.7.7 + 3.5.3 + 9.2.0 + 0.22.0 + 3.9.1 + 2024.5.1 + + 4.12.0 + 4.1.0 + + 0.16.0 + 0.7.0 + + 4.13.1 + 3.11.0 + 3.1.2 + 3.5.2 + 3.5.0 + 3.3.0 + 0.8.10 + 1.5.0 + 3.1.1 + 2.2.3 + 3.7.0 + 3.5.0 + 4.0.0-M13 + 3.4.5 + 3.3.0 + 0.0.43 + 1.0.0-alpha.5 + 0.0.4 + 3.5.0 + true + true + 9.3 + 0.0.43 + 3.2.8 + false + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven-checkstyle-plugin.version} + + + com.puppycrawl.tools + checkstyle + ${puppycrawl-tools-checkstyle.version} + + + io.spring.javaformat + spring-javaformat-checkstyle + ${spring-javaformat-checkstyle.version} + + + + + checkstyle-validation + validate + true + + ${disable.checks} + src/checkstyle/checkstyle.xml + src/checkstyle/checkstyle-header.txt + true + checkstyle.build.directory=${project.build.directory} checkstyle.suppressions.file=${project.basedir}/src/checkstyle/checkstyle-suppressions.xml checkstyle.additional.suppressions.file=${project.basedir}/src/checkstyle/checkstyle-suppressions.xml checkstyle.header.file=${project.basedir}/src/checkstyle/checkstyle-header.txt - true - ${maven-checkstyle-plugin.failsOnError} + true + ${maven-checkstyle-plugin.failsOnError} - + ${maven-checkstyle-plugin.failOnViolation} - - - check - - - - - - org.apache.maven.plugins - maven-site-plugin - ${maven-site-plugin.version} - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - ${java.version} - true - - - - compile - - compile - - - - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/main/java - - - - - test-compile - - test-compile - - - - ${project.basedir}/src/test/kotlin - ${project.basedir}/src/test/java - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - - -parameters - - - - - - default-compile - none - - - - default-testCompile - none - - - java-compile - compile - - compile - - - - java-test-compile - test-compile - - testCompile - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - ${surefireArgLine} - - false - false - - - plain - - - false - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven-jar-plugin.version} - - - - ${project.artifactId} - ${project.version} - - - - - - org.apache.maven.plugins - maven-source-plugin - ${maven-source-plugin.version} - - - generate-sources - package - - jar - - - - - - org.codehaus.mojo - flatten-maven-plugin - ${flatten-maven-plugin.version} - - - flatten - process-resources - - flatten - - - true - ossrh - - remove - remove - remove - keep - keep - resolve - - - - - clean - clean - - clean - - - - - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy-plugin.version} - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - + + + check + + + + + + org.apache.maven.plugins + maven-site-plugin + ${maven-site-plugin.version} + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + ${java.version} + true + + + + compile + + compile + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + + + + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + + -parameters + + + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + ${surefireArgLine} + false + false + + plain + + false + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + ${project.artifactId} + ${project.version} + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + generate-sources + package + + jar + + + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + + flatten + process-resources + + flatten + + + true + ossrh + + remove + remove + remove + keep + keep + resolve + + + + + clean + clean + + clean + + + + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + ${project.basedir}/spring-ai-docs/src/main/javadoc/overview.html - false - false - false - none - - - - generate-javadocs - package - - jar - - - - - - - - - - - format-check - - - env.CI - true - - - - - - io.spring.javaformat - spring-javaformat-maven-plugin - ${spring-javaformat-maven-plugin.version} - - - validate - true - - validate - - - - - - - - - - - format-apply - - - !env.CI - - - - - - io.spring.javaformat - spring-javaformat-maven-plugin - ${spring-javaformat-maven-plugin.version} - - - process-sources - true - - apply - - - - - - - - - - - license - - false - - - - - com.mycila - license-maven-plugin - 4.1 - - - validate - - check - - - - - - the original author or authors. - - 2024 - - - - - Copyright 2023 - ${year} the original author or + false + false + false + none + + + + generate-javadocs + package + + jar + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + test + + report + + + coverageReport + + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 3.2.5 + + testReport + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + 0.0.40 + + + + + + + + + + format-check + + + env.CI + true + + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + ${spring-javaformat-maven-plugin.version} + + + validate + true + + validate + + + + + + + + + format-apply + + + !env.CI + + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + ${spring-javaformat-maven-plugin.version} + + + process-sources + true + + apply + + + + + + + + + license + + false + + + + + com.mycila + license-maven-plugin + 4.1 + + + validate + + check + + + + + + the original author or authors. + + 2024 + + + + + + Copyright 2023 - ${year} the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -695,401 +680,395 @@ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the - License. - - - **/.antlr/** - **/aot.factories - **/.sdkmanrc - **/*.adoc - **/*.puml - **/pom.xml - **/*.properties - **/*.yaml - **/*.yml - **/*.map - **/*.html - **/*.xhtml - **/*.jsp - **/*.js - **/*.css - **/*.txt - **/*.xjb - **/*.ftl - **/*.xsd - **/*.xml - **/*.sh - **/generated/** - **/Dockerfile - - - - - - - - - - - integration-tests - - false - - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - - - integration-test - verify - - - - - - - - - - ci-fast-integration-tests - - false - - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - + + + **/.antlr/** + **/aot.factories + **/.sdkmanrc + **/*.adoc + **/*.puml + **/pom.xml + **/*.properties + **/*.yaml + **/*.yml + **/*.map + **/*.html + **/*.xhtml + **/*.jsp + **/*.js + **/*.css + **/*.txt + **/*.xjb + **/*.ftl + **/*.xsd + **/*.xml + **/*.sh + **/generated/** + **/Dockerfile + + + + + + + + + + integration-tests + + false + + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + + integration-test + verify + + + + + + + + + ci-fast-integration-tests + + false + + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + - - - - org.springframework.ai.chat.memory/**/*IT.java - - - org.springframework.ai.anthropic/**/*IT.java - org.springframework.ai.azure.openai/**/*IT.java - org.springframework.ai.bedrock/**/*IT.java - org.springframework.ai.bedrock.converse/**/*IT.java - org.springframework.ai.elevenlabs/**/*IT.java - org.springframework.ai.huggingface/**/*IT.java - org.springframework.ai.minimax/**/*IT.java - org.springframework.ai.mistralai/**/*IT.java - org.springframework.ai.oci/**/*IT.java - org.springframework.ai.ollama/**/*IT.java - org.springframework.ai.postgresml/**/*IT.java - org.springframework.ai.stabilityai/**/*IT.java - org.springframework.ai.transformers/**/*IT.java - org.springframework.ai.vertexai.embedding/**/*IT.java - org.springframework.ai.vertexai.gemini/**/*IT.java - org.springframework.ai.zhipuai/**/*IT.java - - - org.springframework.ai.vectorstore**/CosmosDB**IT.java - org.springframework.ai.vectorstore.azure/**IT.java - org.springframework.ai.vectorstore**/Cassandra**IT.java - org.springframework.ai.chroma/**IT.java - - org.springframework.ai.vectorstore**/Coherence**IT.java - org.springframework.ai.vectorstore**/Elasticsearch**IT.java - org.springframework.ai.vectorstore**/GemFire**IT.java - org.springframework.ai.vectorstore**/Hana**IT.java - org.springframework.ai.vectorstore**/Hana**IT.java - org.springframework.ai.vectorstore**/Milvus**IT.java - org.springframework.ai.vectorstore**/MariaDB**IT.java - org.springframework.ai.vectorstore**/Mongo**IT.java - org.springframework.ai.vectorstore**/Neo4j**IT.java - org.springframework.ai.vectorstore**/OpenSearch**IT.java - org.springframework.ai.vectorstore**/Oracle**IT.java - - org.springframework.ai.vectorstore**/Pinecone**IT.java - org.springframework.ai.vectorstore.qdrant/**/**IT.java - org.springframework.ai.vectorstore**/Qdrant**IT.java - org.springframework.ai.vectorstore**/Redis**IT.java - org.springframework.ai.vectorstore**/Typesense**IT.java - org.springframework.ai.vectorstore**/Weaviate**IT.java - - - - - - org.springframework.ai.autoconfigure.anthropic/**/**IT.java - org.springframework.ai.autoconfigure.azure/**/**IT.java - org.springframework.ai.autoconfigure.bedrock/**/**IT.java - org.springframework.ai.autoconfigure.huggingface/**/**IT.java - - org.springframework.ai.autoconfigure.chat/**/**IT.java - org.springframework.ai.autoconfigure.elevenlabs/**/**IT.java - org.springframework.ai.autoconfigure.embedding/**/**IT.java - org.springframework.ai.autoconfigure.image/**/**IT.java - - - org.springframework.ai.autoconfigure.minimax/**/**IT.java - org.springframework.ai.autoconfigure.mistralai/**/**IT.java - org.springframework.ai.autoconfigure.oci/**/**IT.java - org.springframework.ai.autoconfigure.ollama/**/**IT.java - - org.springframework.ai.autoconfigure.postgresml/**/**IT.java - - org.springframework.ai.autoconfigure.retry/**/**IT.java - - org.springframework.ai.autoconfigure.stabilityai/**/**IT.java - org.springframework.ai.autoconfigure.transformers/**/**IT.java - - org.springframework.ai.autoconfigure.vectorstore/**/**IT.java - - org.springframework.ai.autoconfigure.vertexai/**/**IT.java - org.springframework.ai.autoconfigure.zhipuai/**/**IT.java - - org.springframework.ai.autoconfigure.zhipuai/**/**IT.java - - - org.springframework.ai.testcontainers/**/**IT.java - - - org.springframework.ai.docker.compose/**/**IT.java - - - org.springframework.ai.integration.tests/**/**IT.java - - - + org.springframework.ai.chat.memory/**/*IT.java + + org.springframework.ai.anthropic/**/*IT.java + org.springframework.ai.azure.openai/**/*IT.java + org.springframework.ai.bedrock/**/*IT.java + org.springframework.ai.bedrock.converse/**/*IT.java + org.springframework.ai.elevenlabs/**/*IT.java + org.springframework.ai.huggingface/**/*IT.java + org.springframework.ai.minimax/**/*IT.java + org.springframework.ai.mistralai/**/*IT.java + org.springframework.ai.oci/**/*IT.java + org.springframework.ai.ollama/**/*IT.java + + org.springframework.ai.postgresml/**/*IT.java + org.springframework.ai.stabilityai/**/*IT.java + org.springframework.ai.transformers/**/*IT.java + org.springframework.ai.vertexai.embedding/**/*IT.java + org.springframework.ai.vertexai.gemini/**/*IT.java + org.springframework.ai.zhipuai/**/*IT.java + + org.springframework.ai.vectorstore**/CosmosDB**IT.java + org.springframework.ai.vectorstore.azure/**IT.java + org.springframework.ai.vectorstore**/Cassandra**IT.java + org.springframework.ai.chroma/**IT.java + + org.springframework.ai.vectorstore**/Coherence**IT.java + org.springframework.ai.vectorstore**/Elasticsearch**IT.java + org.springframework.ai.vectorstore**/GemFire**IT.java + org.springframework.ai.vectorstore**/Hana**IT.java + org.springframework.ai.vectorstore**/Hana**IT.java + org.springframework.ai.vectorstore**/Milvus**IT.java + org.springframework.ai.vectorstore**/MariaDB**IT.java + org.springframework.ai.vectorstore**/Mongo**IT.java + org.springframework.ai.vectorstore**/Neo4j**IT.java + org.springframework.ai.vectorstore**/OpenSearch**IT.java + org.springframework.ai.vectorstore**/Oracle**IT.java + + org.springframework.ai.vectorstore**/Pinecone**IT.java + org.springframework.ai.vectorstore.qdrant/**/**IT.java + org.springframework.ai.vectorstore**/Qdrant**IT.java + org.springframework.ai.vectorstore**/Redis**IT.java + org.springframework.ai.vectorstore**/Typesense**IT.java + org.springframework.ai.vectorstore**/Weaviate**IT.java + + + org.springframework.ai.autoconfigure.anthropic/**/**IT.java + org.springframework.ai.autoconfigure.azure/**/**IT.java + org.springframework.ai.autoconfigure.bedrock/**/**IT.java + org.springframework.ai.autoconfigure.huggingface/**/**IT.java + org.springframework.ai.autoconfigure.chat/**/**IT.java + org.springframework.ai.autoconfigure.elevenlabs/**/**IT.java + org.springframework.ai.autoconfigure.embedding/**/**IT.java + org.springframework.ai.autoconfigure.image/**/**IT.java + org.springframework.ai.autoconfigure.minimax/**/**IT.java + org.springframework.ai.autoconfigure.mistralai/**/**IT.java + org.springframework.ai.autoconfigure.oci/**/**IT.java + org.springframework.ai.autoconfigure.ollama/**/**IT.java + + org.springframework.ai.autoconfigure.postgresml/**/**IT.java + org.springframework.ai.autoconfigure.retry/**/**IT.java + org.springframework.ai.autoconfigure.stabilityai/**/**IT.java + org.springframework.ai.autoconfigure.transformers/**/**IT.java + org.springframework.ai.autoconfigure.vectorstore/**/**IT.java + org.springframework.ai.autoconfigure.vertexai/**/**IT.java + org.springframework.ai.autoconfigure.zhipuai/**/**IT.java + org.springframework.ai.autoconfigure.zhipuai/**/**IT.java + + org.springframework.ai.testcontainers/**/**IT.java + + org.springframework.ai.docker.compose/**/**IT.java + + org.springframework.ai.integration.tests/**/**IT.java + + - - - - - integration-test - verify - - - - - - - - - test-coverage - - - - org.jacoco - jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - prepare-agent - - prepare-agent - - - - report - - report - - - - - - - - - artifactory-staging - - - spring-staging - https://repo.spring.io/libs-staging-local - - false - - - - - - artifactory-milestone - - - spring-milestones - https://repo.spring.io/libs-milestone-local - - false - - - - - - sonatype - - true - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven-gpg-plugin.version} - - - sign-artifacts - verify - - sign - - - - - - - - - org.sonatype.central - central-publishing-maven-plugin - true - - central - true - spring-ai-integration-tests - - - - - - - - - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - io.modelcontextprotocol.sdk - mcp-bom - ${mcp.sdk.version} - pom - import - - - - - - - Central Portal Snapshots - central-portal-snapshots - https://central.sonatype.com/repository/maven-snapshots/ - - false - - - true - - - - maven-central - https://repo.maven.apache.org/maven2/ - - true - - - true - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - - mpollack - Mark Pollack - mpollack at vmware.com - VMware - http://www.spring.io - - lead - - - - tzolov - Christian Tzolov - christian tzolov at broadcom.com - Broadcom - http://www.spring.io - - lead - - - - - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - ${maven-project-info-reports-plugin.version} - - true - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${maven-checkstyle-plugin.version} - - - - checkstyle - - - - - src/checkstyle/checkstyle.xml - src/checkstyle/checkstyle-header.txt - + + + + + integration-test + verify + + + + + + + + + test-coverage + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + prepare-agent + + prepare-agent + + + + report + + report + + + + + + + + + artifactory-staging + + + spring-staging + https://repo.spring.io/libs-staging-local + + false + + + + + + artifactory-milestone + + + spring-milestones + https://repo.spring.io/libs-milestone-local + + false + + + + + + sonatype + + true + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + sign-artifacts + verify + + sign + + + + + + + + + org.sonatype.central + central-publishing-maven-plugin + true + + central + true + spring-ai-integration-tests + + + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + io.modelcontextprotocol.sdk + mcp-bom + ${mcp.sdk.version} + pom + import + + + org.junit.jupiter + junit-jupiter + 5.5.2 + + + + org.mockito + mockito-junit-jupiter + 2.23.4 + + + + io.spring.javaformat + spring-javaformat-formatter + 0.0.40 + + + + + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + + maven-central + https://repo.maven.apache.org/maven2/ + + true + + + true + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + mpollack + Mark Pollack + mpollack at vmware.com + VMware + http://www.spring.io + + lead + + + + tzolov + Christian Tzolov + christian tzolov at broadcom.com + Broadcom + http://www.spring.io + + lead + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + ${maven-project-info-reports-plugin.version} + + true + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven-checkstyle-plugin.version} + + + + checkstyle + + + + + src/checkstyle/checkstyle.xml + src/checkstyle/checkstyle-header.txt + checkstyle.build.directory=${project.build.directory} checkstyle.suppressions.file=${project.basedir}/src/checkstyle/checkstyle-suppressions.xml checkstyle.additional.suppressions.file=${project.basedir}/src/checkstyle/checkstyle-suppressions.xml checkstyle.header.file=${project.basedir}/src/checkstyle/checkstyle-header.txt - - - - - - + + + + + + \ No newline at end of file diff --git a/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java b/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java new file mode 100644 index 00000000000..5bda0b78628 --- /dev/null +++ b/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java @@ -0,0 +1,315 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ai.vectorstore.neo4j.filter; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.ai.vectorstore.filter.Filter; +import org.springframework.ai.vectorstore.filter.Filter.Expression; +import org.springframework.ai.vectorstore.filter.Filter.Group; +import org.springframework.ai.vectorstore.filter.Filter.Key; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; +import org.junit.jupiter.api.*; +import org.springframework.ai.vectorstore.filter.converter.AbstractFilterExpressionConverter; + +class Neo4JVectorFilterExpressionConverterDoExpressionTest { + + private Neo4jVectorFilterExpressionConverter converter; + + @Mock + private Filter.Operand leftOperand; + + @Mock + private Filter.Operand rightOperand; + + @Mock + private Key keyOperand; + + @Mock + private Filter.Value valueOperand; + + @Mock + private Group groupOperand; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + converter = spy(new TestableNeo4jVectorFilterExpressionConverter()); + } + + @Test + @Tag("valid") + void expressionWithNinTypeTriggersNotInConversion() { + // Arrange + Expression ninExpression = new Expression(Filter.ExpressionType.NIN, leftOperand, rightOperand); + StringBuilder context = new StringBuilder(); + + doNothing().when(converter).doNot(any(Expression.class), eq(context)); + + // Act + converter.doExpression(ninExpression, context); + + // Assert + ArgumentCaptor expressionCaptor = ArgumentCaptor.forClass(Expression.class); + verify(converter, times(1)).doNot(expressionCaptor.capture(), eq(context)); + + Expression capturedExpression = expressionCaptor.getValue(); + assertEquals(Filter.ExpressionType.NOT, capturedExpression.type()); + + Expression innerExpression = (Expression) capturedExpression.left(); + assertEquals(Filter.ExpressionType.IN, innerExpression.type()); + assertEquals(leftOperand, innerExpression.left()); + assertEquals(rightOperand, innerExpression.right()); + } + + @Test + @Tag("valid") + void expressionWithEqTypeProcessesOperandsAndSymbolDirectly() { + // Arrange + Expression eqExpression = new Expression(Filter.ExpressionType.EQ, leftOperand, rightOperand); + StringBuilder context = new StringBuilder(); + + doNothing().when(converter).convertOperand(any(), any()); + when(converter.getOperationSymbol(eqExpression)).thenReturn(" = "); + + // Act + converter.doExpression(eqExpression, context); + + // Assert + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(eqExpression); + assertEquals(" = ", context.toString()); + } + + @Test + @Tag("valid") + void expressionWithGtTypeAppendsCorrectOperationSymbol() { + // Arrange + Expression gtExpression = new Expression(Filter.ExpressionType.GT, keyOperand, valueOperand); + StringBuilder context = new StringBuilder(); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("key"); + return null; + }).when(converter).convertOperand(eq(keyOperand), eq(context)); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("value"); + return null; + }).when(converter).convertOperand(eq(valueOperand), eq(context)); + + when(converter.getOperationSymbol(gtExpression)).thenReturn(" > "); + + // Act + converter.doExpression(gtExpression, context); + + // Assert + assertEquals("key > value", context.toString()); + verify(converter, times(1)).convertOperand(keyOperand, context); + verify(converter, times(1)).getOperationSymbol(gtExpression); + verify(converter, times(1)).convertOperand(valueOperand, context); + } + + @Test + @Tag("valid") + void expressionWithComplexNestedOperandsProcessesCorrectly() { + // Arrange + Expression ltExpression = new Expression(Filter.ExpressionType.LT, groupOperand, leftOperand); + StringBuilder context = new StringBuilder(); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("(nested_group)"); + return null; + }).when(converter).convertOperand(eq(groupOperand), eq(context)); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("operand"); + return null; + }).when(converter).convertOperand(eq(leftOperand), eq(context)); + + when(converter.getOperationSymbol(ltExpression)).thenReturn(" < "); + + // Act + assertDoesNotThrow(() -> converter.doExpression(ltExpression, context)); + + // Assert + verify(converter, times(1)).convertOperand(groupOperand, context); + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).getOperationSymbol(ltExpression); + assertEquals("(nested_group) < operand", context.toString()); + } + + @Test + @Tag("boundary") + void ninExpressionWithNullOperandsHandlesGracefully() { + // Arrange + Expression ninExpression = new Expression(Filter.ExpressionType.NIN, null, rightOperand); + StringBuilder context = new StringBuilder(); + + doNothing().when(converter).doNot(any(Expression.class), eq(context)); + + // Act + assertDoesNotThrow(() -> converter.doExpression(ninExpression, context)); + + // Assert + ArgumentCaptor expressionCaptor = ArgumentCaptor.forClass(Expression.class); + verify(converter, times(1)).doNot(expressionCaptor.capture(), eq(context)); + + Expression capturedExpression = expressionCaptor.getValue(); + assertEquals(Filter.ExpressionType.NOT, capturedExpression.type()); + + Expression innerExpression = (Expression) capturedExpression.left(); + assertEquals(Filter.ExpressionType.IN, innerExpression.type()); + assertNull(innerExpression.left()); + assertEquals(rightOperand, innerExpression.right()); + } + + @Test + @Tag("valid") + void expressionWithInTypeProcessesThroughStandardPath() { + // Arrange + Expression inExpression = new Expression(Filter.ExpressionType.IN, leftOperand, rightOperand); + StringBuilder context = new StringBuilder(); + + doNothing().when(converter).convertOperand(any(), any()); + when(converter.getOperationSymbol(inExpression)).thenReturn(" IN "); + + // Act + converter.doExpression(inExpression, context); + + // Assert + verify(converter, never()).doNot(any(), any()); + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(inExpression); + assertEquals(" IN ", context.toString()); + } + + @Test + @Tag("integration") + void multipleSequentialExpressionsModifyContextCorrectly() { + // Arrange + Expression eqExpression = new Expression(Filter.ExpressionType.EQ, leftOperand, rightOperand); + Expression gtExpression = new Expression(Filter.ExpressionType.GT, keyOperand, valueOperand); + Expression ltExpression = new Expression(Filter.ExpressionType.LT, leftOperand, rightOperand); + StringBuilder context = new StringBuilder(); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("left"); + return null; + }).when(converter).convertOperand(eq(leftOperand), eq(context)); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("right"); + return null; + }).when(converter).convertOperand(eq(rightOperand), eq(context)); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("key"); + return null; + }).when(converter).convertOperand(eq(keyOperand), eq(context)); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("value"); + return null; + }).when(converter).convertOperand(eq(valueOperand), eq(context)); + + when(converter.getOperationSymbol(eqExpression)).thenReturn("="); + when(converter.getOperationSymbol(gtExpression)).thenReturn(">"); + when(converter.getOperationSymbol(ltExpression)).thenReturn("<"); + + // Act + converter.doExpression(eqExpression, context); + converter.doExpression(gtExpression, context); + converter.doExpression(ltExpression, context); + + // Assert + assertEquals("left=rightkeyvalue>leftvalue", context.toString()); + verify(converter, times(4)).convertOperand(eq(leftOperand), eq(context)); + verify(converter, times(2)).convertOperand(eq(rightOperand), eq(context)); + verify(converter, times(1)).convertOperand(eq(keyOperand), eq(context)); + verify(converter, times(1)).convertOperand(eq(valueOperand), eq(context)); + } + + @Test + @Tag("valid") + void emptyStringBuilderContextReceivesExpressionContent() { + // Arrange + Expression eqExpression = new Expression(Filter.ExpressionType.EQ, leftOperand, rightOperand); + StringBuilder context = new StringBuilder(); + assertTrue(context.length() == 0); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("field"); + return null; + }).when(converter).convertOperand(eq(leftOperand), eq(context)); + + doAnswer(invocation -> { + StringBuilder sb = invocation.getArgument(1); + sb.append("'value'"); + return null; + }).when(converter).convertOperand(eq(rightOperand), eq(context)); + + when(converter.getOperationSymbol(eqExpression)).thenReturn(" = "); + + // Act + converter.doExpression(eqExpression, context); + + // Assert + assertFalse(context.length() == 0); + assertEquals("field = 'value'", context.toString()); + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).getOperationSymbol(eqExpression); + verify(converter, times(1)).convertOperand(rightOperand, context); + } + + private static class TestableNeo4jVectorFilterExpressionConverter extends Neo4jVectorFilterExpressionConverter { + + @Override + protected void doNot(Expression expression, StringBuilder context) { + // Mock implementation for testing + } + + @Override + protected void convertOperand(Filter.Operand operand, StringBuilder context) { + // Mock implementation for testing + } + + @Override + protected String getOperationSymbol(Expression expression) { + // Mock implementation for testing + return ""; + } + + } + +} \ No newline at end of file diff --git a/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java new file mode 100644 index 00000000000..a4d7ab11d35 --- /dev/null +++ b/vector-stores/spring-ai-neo4j-store/src/test/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4JVectorFilterExpressionConverterDoExpressionTest.java @@ -0,0 +1,254 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.ai.vectorstore.neo4j.filter; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.ai.vectorstore.filter.Filter; +import org.springframework.ai.vectorstore.filter.Filter.Expression; +import org.springframework.ai.vectorstore.filter.Filter.Group; +import org.springframework.ai.vectorstore.filter.Filter.Key; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import org.junit.jupiter.api.*; +import org.springframework.ai.vectorstore.filter.converter.AbstractFilterExpressionConverter; + +@ExtendWith(MockitoExtension.class) +public class Neo4JVectorFilterExpressionConverterDoExpressionTest { + + @Spy + private Neo4jVectorFilterExpressionConverter converter; + + @Mock + private Filter.Operand leftOperand; + + @Mock + private Filter.Operand rightOperand; + + @Mock + private Key keyOperand; + + @Mock + private Filter.Value valueOperand; + + @Mock + private Group groupOperand; + + private StringBuilder context; + + @BeforeEach + void setUp() { + context = new StringBuilder(); + doNothing().when(converter).convertOperand(any(), any()); + when(converter.getOperationSymbol(any())).thenReturn(" = "); + doNothing().when(converter).doNot(any(), any()); + } + + @Test + @Tag("valid") + void expressionWithNinTypeTriggersNotInConversion() { + // Arrange + Expression ninExpression = new Expression(Filter.ExpressionType.NIN, leftOperand, rightOperand); + // Act + converter.doExpression(ninExpression, context); + // Assert + verify(converter, times(1)).doNot(any(Expression.class), eq(context)); + verify(converter, never()).convertOperand(any(), any()); + verify(converter, never()).getOperationSymbol(any()); + } + + @Test + @Tag("valid") + void expressionWithEqTypeProcessesOperandsAndSymbolDirectly() { + // Arrange + Expression eqExpression = new Expression(Filter.ExpressionType.EQ, leftOperand, rightOperand); + when(converter.getOperationSymbol(eqExpression)).thenReturn(" = "); + // Act + converter.doExpression(eqExpression, context); + // Assert + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(eqExpression); + verify(converter, never()).doNot(any(), any()); + assertEquals(" = ", context.toString()); + } + + @Test + @Tag("valid") + void expressionWithGtTypeAppendsCorrectOperationSymbol() { + // Arrange + Expression gtExpression = new Expression(Filter.ExpressionType.GT, keyOperand, valueOperand); + when(converter.getOperationSymbol(gtExpression)).thenReturn(" > "); + // Act + converter.doExpression(gtExpression, context); + // Assert + verify(converter, times(1)).convertOperand(keyOperand, context); + verify(converter, times(1)).convertOperand(valueOperand, context); + verify(converter, times(1)).getOperationSymbol(gtExpression); + assertEquals(" > ", context.toString()); + } + + @Test + @Tag("valid") + void expressionWithComplexNestedOperandsProcessesCorrectly() { + // Arrange + Expression nestedExpression = new Expression(Filter.ExpressionType.LT, leftOperand, rightOperand); + Expression ltExpression = new Expression(Filter.ExpressionType.LT, groupOperand, nestedExpression); + when(converter.getOperationSymbol(ltExpression)).thenReturn(" < "); + // Act + assertDoesNotThrow(() -> converter.doExpression(ltExpression, context)); + // Assert + verify(converter, times(1)).convertOperand(groupOperand, context); + verify(converter, times(1)).convertOperand(nestedExpression, context); + verify(converter, times(1)).getOperationSymbol(ltExpression); + assertEquals(" < ", context.toString()); + } + + @Test + @Tag("boundary") + void ninExpressionWithNullOperandsHandlesGracefully() { + // Arrange + Expression ninExpression = new Expression(Filter.ExpressionType.NIN, null, rightOperand); + // Act + assertDoesNotThrow(() -> converter.doExpression(ninExpression, context)); + // Assert + verify(converter, times(1)).doNot(any(Expression.class), eq(context)); + verify(converter, never()).convertOperand(any(), any()); + verify(converter, never()).getOperationSymbol(any()); + } + + @Test + @Tag("valid") + void expressionWithInTypeProcessesThroughStandardPath() { + // Arrange + Expression inExpression = new Expression(Filter.ExpressionType.IN, leftOperand, rightOperand); + when(converter.getOperationSymbol(inExpression)).thenReturn(" IN "); + // Act + converter.doExpression(inExpression, context); + // Assert + verify(converter, never()).doNot(any(), any()); + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(inExpression); + assertEquals(" IN ", context.toString()); + } + + @Test + @Tag("integration") + void multipleSequentialExpressionsModifyContextCorrectly() { + // Arrange + Expression eqExpression = new Expression(Filter.ExpressionType.EQ, leftOperand, rightOperand); + Expression gtExpression = new Expression(Filter.ExpressionType.GT, keyOperand, valueOperand); + Expression ltExpression = new Expression(Filter.ExpressionType.LT, groupOperand, leftOperand); + when(converter.getOperationSymbol(eqExpression)).thenReturn(" = "); + when(converter.getOperationSymbol(gtExpression)).thenReturn(" > "); + when(converter.getOperationSymbol(ltExpression)).thenReturn(" < "); + // Act + converter.doExpression(eqExpression, context); + converter.doExpression(gtExpression, context); + converter.doExpression(ltExpression, context); + // Assert + verify(converter, times(6)).convertOperand(any(), eq(context)); + verify(converter, times(3)).getOperationSymbol(any()); + assertEquals(" = > < ", context.toString()); + } + + @Test + @Tag("valid") + void emptyStringBuilderContextReceivesExpressionContent() { + // Arrange + Expression eqExpression = new Expression(Filter.ExpressionType.EQ, leftOperand, rightOperand); + when(converter.getOperationSymbol(eqExpression)).thenReturn(" = "); + assertTrue(context.length() == 0); + // Act + converter.doExpression(eqExpression, context); + // Assert + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(eqExpression); + assertEquals(" = ", context.toString()); + assertTrue(context.length() > 0); + } + + @Test + @Tag("boundary") + void ninExpressionWithBothNullOperandsHandlesGracefully() { + // Arrange + Expression ninExpression = new Expression(Filter.ExpressionType.NIN, null, null); + // Act + assertDoesNotThrow(() -> converter.doExpression(ninExpression, context)); + // Assert + verify(converter, times(1)).doNot(any(Expression.class), eq(context)); + verify(converter, never()).convertOperand(any(), any()); + verify(converter, never()).getOperationSymbol(any()); + } + + @Test + @Tag("valid") + void expressionWithNeTypeProcessesThroughStandardPath() { + // Arrange + Expression neExpression = new Expression(Filter.ExpressionType.NE, leftOperand, rightOperand); + when(converter.getOperationSymbol(neExpression)).thenReturn(" <> "); + // Act + converter.doExpression(neExpression, context); + // Assert + verify(converter, never()).doNot(any(), any()); + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(neExpression); + assertEquals(" <> ", context.toString()); + } + + @Test + @Tag("valid") + void expressionWithGteTypeProcessesThroughStandardPath() { + // Arrange + Expression gteExpression = new Expression(Filter.ExpressionType.GTE, keyOperand, valueOperand); + when(converter.getOperationSymbol(gteExpression)).thenReturn(" >= "); + // Act + converter.doExpression(gteExpression, context); + // Assert + verify(converter, never()).doNot(any(), any()); + verify(converter, times(1)).convertOperand(keyOperand, context); + verify(converter, times(1)).convertOperand(valueOperand, context); + verify(converter, times(1)).getOperationSymbol(gteExpression); + assertEquals(" >= ", context.toString()); + } + + @Test + @Tag("valid") + void expressionWithLteTypeProcessesThroughStandardPath() { + // Arrange + Expression lteExpression = new Expression(Filter.ExpressionType.LTE, leftOperand, rightOperand); + when(converter.getOperationSymbol(lteExpression)).thenReturn(" <= "); + // Act + converter.doExpression(lteExpression, context); + // Assert + verify(converter, never()).doNot(any(), any()); + verify(converter, times(1)).convertOperand(leftOperand, context); + verify(converter, times(1)).convertOperand(rightOperand, context); + verify(converter, times(1)).getOperationSymbol(lteExpression); + assertEquals(" <= ", context.toString()); + } + +} \ No newline at end of file