Commit Graph

44 Commits

Author SHA1 Message Date
greymoth e3ded475a9
Escape LIKE wildcards in Milvus containsString filter (match #5522/#5553) (#5600)
`MilvusMetadataFilterMapper.mapContains` builds a `ContainsString` query
as `field LIKE "%" + value + "%"` but never escapes the user value's own
LIKE wildcards. In Milvus, `%` and `_` are wildcards, so
`containsString("50%")` matches "50" + anything and
`containsString("a_b")` matches "axb" — but the contract is a literal
substring (`ContainsString#test` uses `String#contains`).

Parent PR #5577 hardened the same mapper's `formatValue` against
string-literal breakout but left the wildcard side undone. The identical
defect was already fixed in the Hibernate (#5522) and MongoDB (#5553)
mappers; Milvus is the store the sweep missed.

The fix adds a `formatLikePattern` that escapes `\`, `%`, `_`, `"` (the
existing `formatValue` is left untouched — its backslash-doubling would
corrupt `\%`). +4 regression tests. Verified by execution (Java 21): the
wildcard cases fail on the old code and pass after; non-wildcard values
are byte-identical.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 10:26:40 +02:00
Eunbin Son 8dc19c46ec
fix: Escape backslashes in Milvus metadata filter values (#5577)
## Issue
Closes #5576

## Change
`MilvusMetadataFilterMapper.formatValue()` escaped double quotes but not
backslashes. Milvus treats backslash as the escape character in string
literals (`\\` represents a literal `\`), so a value containing a
backslash (e.g. a Windows path) produced a malformed expression — either
misinterpreted (`\b` → backspace) or rejected as an invalid escape
sequence. This affected every operator, `IsIn`/`IsNotIn`, and
`removeAll(ids)`, since all route through `formatValue`/`formatValues`.

Fix: escape backslashes first, then double quotes (`replace("\\",
"\\\\").replace("\"", "\\\"")`), mirroring sibling stores
(azure-cosmos-nosql, infinispan, pgvector). One production line. Added
`MilvusMetadataFilterMapperTest` (pure unit test) asserting the exact
generated expression for backslash, backslash+quote, collection values,
and a no-special-character regression. Values without backslashes are
unchanged — the only behaviour change is for backslash values, which
previously produced an invalid expression.

## General checklist
- [X] There are no breaking changes (API, behaviour)
- [X] I have added unit and/or integration tests for my change
- [X] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
<!-- Unit tests green (6/6). The *IT are Testcontainers Docker-gated and
were not run locally. -->
- [ ] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
<!-- Not run locally; change is isolated to langchain4j-milvus. -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
<!-- Will add after review if requested. -->
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
<!-- N/A — small bug fix. -->
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
<!-- N/A -->

<!-- Checklist for adding new maven module: N/A — no new module. -->
<!-- Checklist for adding new embedding store integration: N/A — not a
new integration. -->

## Checklist for changing existing embedding store integration
- [ ] I have manually verified that the `MilvusEmbeddingStore` works
correctly with the data persisted using the latest released version of
LangChain4j
<!-- N/A — change only affects filter-expression string escaping, not
the persisted data format. -->
2026-06-25 09:52:13 +02:00
Xuan Cui ab644a659c
Fix Milvus L2 relevance score mapping (#5428)
## Summary
- Convert Milvus L2 distances to relevance scores with lower distance
mapped higher.
- Pass the configured Milvus metric type into result mapping.
- Add mapper unit coverage for L2 and non-L2 score conversion.

## Verification
- MapperTest passed via Maven with embedding model download skipped.

---------

Co-authored-by: Q1Xuan <242799924+Q1Xuan@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:47:40 +02:00
odysseaspenta 5a023ed992
Added the ability to specify the values of additional parameters in the creation of Milvus indexes (#3464)
## Issue
Closes #3448

## Change
Added the ability to specify additional parameters when building a
MilvusEmbeddingStore that can be passed down during collection and index
creation to customize the behavior of the index created. These
parameters can impact the performance of indexes for large vector
collections.


## General checklist
- [X] There are no breaking changes
- [X] I have added unit and/or integration tests for my change
- [X] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green

## Checklist for changing existing embedding store integration
- [X] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
2025-08-28 09:26:32 +02:00
Tom Cunningham d952d933e0
#3550 Fix typo on field name variables (#3551)
## Issue

Fixes https://github.com/langchain4j/langchain4j/issues/3550

Changes here are limited to constructor arguments, ran spotless apply
because the changes were failing CI without them

## Change

Change "FiledName" variables to FieldName

## General checklist
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ x] There are no breaking changes
- [x ] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
2025-08-18 10:19:51 +02:00
code2t 291123372d
use `withFloatVectors` instead of deprecated `withVectors` (#2642) 2025-08-05 06:27:25 +03:00
Ivan Milosavljević efbdcabbf8
Use isNullOrEmpty and isNullOrBlank functions from Utils class (#3071)
<!--
Thank you so much for your contribution!

Please fill in all the sections below.
Please open the PR as a draft initially. Once it is reviewed and
approved, we will ask you to add documentation and examples.
Please note that PRs with breaking changes or without tests will be
rejected.

Please note that PRs will be reviewed based on the priority of the
issues they address.
We ask for your patience. We are doing our best to review your PR as
quickly as possible.
Please refrain from pinging and asking when it will be reviewed. Thank
you for understanding!
-->

## Issue
<!-- Please specify the ID of the issue this PR is addressing. For
example: "Closes #1234" or "Fixes #1234" -->
Closes #

## Change
<!-- Please describe the changes you made. -->
I noticed that in a lot of files there are duplicated checks for `null`
and not empty or `null` and not blank. Since there exist functions in
`Utils` class which do exactly that, I replaced all custom checks with
calls to such functions.

## General checklist

NB: I purposefully didn't commit formatting changes (i.e., `make lint`
and `make format`) because they'd change many lines in many files, much
more than what I changed in this PR, and that'd make PR difficult to
review. If you think I should do it, I'd gladly commit them.
<!-- Please double-check the following points and mark them like this:
[X] -->
- [x] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [ ] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [ ] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
<!-- Before adding documentation and example(s) (below), please wait
until the PR is reviewed and approved. -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)


## Checklist for adding new maven module
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added my new module in the root `pom.xml` and
`langchain4j-bom/pom.xml`


## Checklist for adding new embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreIT` that extends
from either `EmbeddingStoreIT` or `EmbeddingStoreWithFilteringIT`
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreRemovalIT` that
extends from `EmbeddingStoreWithRemovalIT`

## Checklist for changing existing embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j

---------

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2025-07-01 09:33:33 +02:00
Julien Dubois 828b27f1cb
Merge commit from fork
* Fix SQL injection vulnerability with PGVector, MariaDB and Milvus

- Add a test case for each database
- Fix the SQL injection vulnerability
- This is the same issue for all 3 databases, only Milvus has a different escape character
- I ran the full test suite for all 3 databases to test there is no regression
- This should fix the security warning at https://github.com/langchain4j/langchain4j/security/advisories/GHSA-hvxq-w43p-3ccr

* updated tests

* Fix Milvus test

---------

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2025-06-17 18:26:15 +02:00
Julien Dubois e1ee25994c
Upgrade Milvus SDK to 2.5.9 (#3142)
Fixes #3141 

Main reason for this PR is to fix the security issue detailed in #3141 

This also:

- Updates the Docker image used for tests to the latest version (2.5.10)
- Fixes a Spotless formatting issue

I have run the full test suite, both with TestContainers and using the
Milvus Cloud, and this is all green.
2025-06-03 09:22:51 +02:00
Dmytro Liubarskyi 29f332c2b9 All custom exceptions now extend LangChain4jException 2025-04-15 17:41:11 +02:00
Dmytro Liubarskyi 18a1f2cbb2 Milvus: update to latest versions 2025-04-11 11:58:44 +02:00
Dmytro Liubarskyi fad1e49e7d
Remove deprecated EmbeddingStore.findRelevant API (#2750)
## Change
Removed deprecated `EmbeddingStore.findRelevant()` API.
It was deprecated a while ago and wad replaced with the
`EmbeddingStore.search(EmbeddingSearchRequest)` API

## General checklist
- [ ] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [x] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [x] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [x] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [x] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2025-03-21 17:27:17 +01:00
Tim te Beek 86afe2698e
Apply testing best practices to the project and future pull requests (#2561)
## Issue
As discussed with @dliubarskyi on
-
https://github.com/langchain4j/langchain4j/pull/2437#discussion_r1928261580

## Change
Ran a trio of OpenRewrite recipes to improve the tests here:
1.
[TestsShouldNotBePublic](https://docs.openrewrite.org/recipes/java/testing/cleanup/testsshouldnotbepublic)
2.
[RemoveTestPrefix](https://docs.openrewrite.org/recipes/java/testing/cleanup/removetestprefix)
3.
[Assertj](https://docs.openrewrite.org/recipes/java/testing/assertj/assertj-best-practices)

This was followed by some light touch ups, and applying Spotless to any
changed files.
I've also added the recipes to those enforced on future PRs, and applied
minor fixes to that workflow.

Already ran the tests on a fork PR, to verify the integration
- https://github.com/timtebeek/langchain4j/pull/1

## General checklist
- [x] There are no breaking changes
- [x] I have added unit and/or integration tests for my change
- [x] The tests cover both positive and negative cases
- [x] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [x] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
<!-- Before adding documentation and example(s) (below), please wait
until the PR is reviewed and approved. -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2025-02-17 11:24:24 +01:00
Mario Fusco a3fe481015
Fix ClassCastException in MilvusEmbeddingStore (#2441)
Fix https://github.com/langchain4j/langchain4j/issues/2438
2025-01-30 17:47:08 +01:00
Florian Hotze 024e9eddd8
Support ContainsString metadata Filter (#2344)
## Change

This PR adds a new MetadataFilters that allows filtering metadata values
by checking whether they contain or not contain a given string.
Whilst this is less powerful than #2342, it is easier to implement in
embedding stores, this PR implements the `ContainsString` filter for the
following embedding stores:

- Milvus
- PgVector
- Qdrant

I tried to implement it for Chroma as well, but didn't find a way in the
Chroma docs to do so.

## General checklist

- [X] There are no breaking changes
- [X] I have added unit and/or integration tests for my change
- [X] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [x] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [x] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
2025-01-28 12:04:24 +01:00
Serdar Basegmez 2067170030
Version upgrade for Milvus integration (#2362)
## Issue
Closes #2332

## Change
Milvus-sdk dependency upgraded to 2.5.3 and test containers to 2.4.20.
Added a simple README.md

## General checklist
- [X] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)


## Checklist for changing existing embedding store integration
- [X] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
2025-01-10 17:57:31 +01:00
Victor 48681d97b5
EmbeddingStore: implement addAll(ids, embeddings, segments) (#2156)
## Issue
Closes #2106 
Contributes to #2160

## Change
Added method `addAll(**ids**, embeddings, embedded)`

## General checklist
- [x] There are no breaking changes
- [ ] I have added unit and integration tests for my change
- [x] I have manually run all the unit tests in the module I have
added/changed, and they are all green
- [x] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2024-12-04 18:00:07 +01:00
Omar dbf180f846
Milvus: option to set MilvusServiceClient (#2042)
## Issue
Closes #2020

## Change
Added an option to set `MilvusServiceClient` when creating
`MilvusEmbeddingStore`

## General checklist
- [x] There are no breaking changes
- [ ] I have added unit and integration tests for my change
- [ ] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [ ] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2024-11-12 14:39:37 +01:00
LangChain4j b6f2cd685f
Fix #1747 (#1949)
## Issue
Fixes #1747

## Change
Fixed this bug for Milvus and Chroma.

Did not manage to fix it for Pinecone because Pinecone can store
`Integer`/`Long` only as `Double`. We could theoretically store them as
`String`s, but then metadata filtering for `Integer`/`Long` values will
not work. For now I've left the comment in the `PineconeEmbeddingStore`
Javadoc and Pinecone documentation about the bug and possible
workaround.

## General checklist
- [X] There are no breaking changes
- [X] I have added unit and integration tests for my change
- [x] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [x] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [X] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2024-10-21 13:38:53 +02:00
Martin7-1 060b07a009
Tiny fix for `EmbeddingStoreWithFilteringIT` (#1925)
## Issue
Closes #1924  

## Change
> This PR is mainly for `ClickHosue` because a column can have only one
type.

1. Change `key2` from `"b"` to `UUID.randomUUID()`.
2. Rename `OracleEmbeddingStoreWithFilteringIT` to
`OracleEmbeddingStoreIT` to keep the consistence with other modules.
3. Add tinylog test dependencies in some modules which has no slf4j
implementation.

For all subclass of `EmbeddingStoreWithFilteringIT`, I have verified
them and they are all green. (except `AzureAiSearch` and `MilvusCloud`,
which I have no api key)

## General checklist
- [x] There are no breaking changes
- [ ] I have added unit and integration tests for my change
- [x] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [x] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green

## Checklist for changing existing embedding store integration
- [x] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
2024-10-15 17:28:36 +02:00
LangChain4j dbfcd7cc30 Milvus: configurable field names (#1852) 2024-10-10 16:52:49 +02:00
hrhrng 2bd251ad14
Milvus: configurable field names (#1852)
## Issue
Closes #1842 

## Change
Add `FieldDefinition` to hold customized filed name.
Replace default field name with customized filed name.

## General checklist
- [X] There are no breaking changes
- [X] I have added unit and integration tests for my change
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)

## Checklist for changing existing embedding store integration
- [X] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
2024-10-10 16:48:14 +02:00
LangChain4j 4d45f5330a Milvus - upgrade to Milvus SDK 2.3.9 (#1642) 2024-08-27 16:08:52 +02:00
Pavel Reshetnik cf27e1dbc5
Milvus - upgrade to Milvus SDK 2.3.9 (#1642)
## Issue
Closes #1629

## Change
Upgrade to Milvus SDK 2.3.9 and replace com.alibaba.fastjson with
com.google.gson

## General checklist
- [X] There are no breaking changes
- [N/A] I have added unit and integration tests for my change
- [+-] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [+-] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green

* I had to skip the MilvusEmbeddingStoreCloudIT test due to a lack of
credentials. However, other Milvus tests passed.
* While the [core] tests were successful, the [main] tests failed
because I lack credentials for several cloud providers.

<!-- Before adding documentation and example(s) (below), please wait
until the PR is reviewed and approved. -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)

## Checklist for adding new model integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added my new module in the
[BOM](https://github.com/langchain4j/langchain4j/blob/main/langchain4j-bom/pom.xml)


## Checklist for adding new embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreIT` that extends
from either `EmbeddingStoreIT` or `EmbeddingStoreWithFilteringIT`
- [ ] I have added my new module in the
[BOM](https://github.com/langchain4j/langchain4j/blob/main/langchain4j-bom/pom.xml)


## Checklist for changing existing embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
2024-08-27 16:06:02 +02:00
LangChain4j 8537e897ba
Fix split packages (#1433)
## Issue
Closes #1066

## Change
These are changes for each split package (each change was done in a
separate commit, so they can be reviewed in isolation):
- `dev.langchain4j.retriever` -> Moved `EmbeddingStoreRetriever` into
`langchain4j-core` module
- `dev.langchain4j.agent.tool` -> Moved `DefaultToolExecutor` and
`ToolExecutor` into `dev.langchain4j.service.tool` package
- `dev.langchain4j.classification` -> Moved `TextClassifier` into
`langchian4j` module
- `dev.langchain4j.chain` -> Moved `Chain` into `langchain4j` module
- `dev.langchain4j.model.embedding` -> [All in-process embedding models
should have unique package
name](https://github.com/langchain4j/langchain4j-embeddings/pull/33)
- `dev.langchain4j.model.output` -> Moved `OutputParser` and all it's
implementations into `dev.langchain4j.service.output` package of the
`langchain4j` module

More details can be found
[here](https://docs.google.com/spreadsheets/d/1U7f2MIfDgWA1tydPpzWpOGTHiBjBVZjsu0uZnXBT9qE/edit?usp=sharing).

## Breaking Changes
- All in-process ONNX model classes moved into their own unique
packages:
- `AllMiniLmL6V2EmbeddingModel` moved into
`dev.langchain4j.model.embedding.onnx.allminilml6v2`
- `AllMiniLmL6V2QuantizedEmbeddingModel` moved into
`dev.langchain4j.model.embedding.onnx.allminilml6v2q`
- `OnnxEmbeddingModel` moved into `dev.langchain4j.model.embedding.onnx`
package
  - etc
- `ToolExecutor` and `DefaultToolExecutor` moved into
`dev.langchain4j.service.tool` package
- Moved `OutputParser` and all it's implementations into
`dev.langchain4j.service.output` package of the `langchain4j` module
- Moved `Chain` into `langchain4j` module
- Moved `TextClassifier` into `langchian4j` module

## General checklist
- [ ] There are no breaking changes
- [ ] I have added unit and integration tests for my change
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
<!-- Before adding documentation and example(s) (below), please wait
until the PR is reviewed and approved. -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2024-07-19 12:59:59 +02:00
humcqc dc0effe67e
[FEATURE] Metadata UUID Support (#1211)
[FEATURE] Metadata UUID Support #1164
2024-06-19 17:56:33 +02:00
LangChain4j 25e4d6de49 cleaned up EmbeddingStore removal functionality 2024-06-13 18:17:21 +02:00
LangChain4j 2c8ff58c02 Milvus: improve insert performance 2024-06-06 16:40:26 +02:00
LangChain4j d29866bde4 Implement embedding removal methods for Milvus embedding store (#1172) 2024-06-06 16:00:01 +02:00
二毛 56c1615703
Implement embedding removal methods for Milvus embedding store (#1172)
## Issue
<!-- Please paste the link to the issue this PR is addressing. For
example: https://github.com/langchain4j/langchain4j/issues/1012 -->
#1168 

## Change
<!-- Please describe the changes you made. -->
Add the `MilvusEmbeddingStore` method to implement `remove(String id)`,
`removeAll(Collection<String> ids)`, `removeAll(Filter filter)`,
`removeAll()`.
Add unit test `MilvusEmbeddingStoreRemoveIT`

## General checklist
<!-- Please double-check the following points and mark them like this:
[X] -->
- [x] There are no breaking changes
- [x] I have added unit and integration tests for my change
- [x] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [ ] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
<!-- Before adding documentation and example(s) (below), please wait
until the PR is reviewed and approved. -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)

## Checklist for changing existing embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
2024-06-06 15:47:09 +02:00
LangChain4j e0b7a2816b added Milvus env var 2024-03-22 09:55:28 +01:00
LangChain4j 498145cb44
fix #715: Improve Milvus integration performance: load collection in memory only when creating MilvusEmbeddingStore (#717) 2024-03-08 17:27:38 +01:00
LangChain4j 1acb7a607f
EmbeddingStore (Metadata) Filter API (#610)
## New EmbeddingStore (metadata) `Filter` API
Many embedding stores, such as
[Pinecone](https://docs.pinecone.io/docs/metadata-filtering) and
[Milvus](https://milvus.io/docs/boolean.md) support strict filtering
(think of an SQL "WHERE" clause) during similarity search.
So, if one has an embedding store with movies, for example, one could
search not only for the most semantically similar movies to the given
user query but also apply strict filtering by metadata fields like year,
genre, rating, etc. In this case, the similarity search will be
performed only on those movies that match the filter expression.

Since LangChain4j supports (and abstracts away) many embedding stores,
there needs to be an embedding-store-agnostic way for users to define
the filter expression.

This PR introduces a `Filter` interface, which can represent both simple
(e.g., `type = "documentation"`) and composite (e.g., `type in
("documentation", "tutorial") AND year > 2020`) filter expressions in an
embedding-store-agnostic manner.

`Filter` currently supports the following operations:

- Comparison:
  - `IsEqualTo`
  - `IsNotEqualTo`
  - `IsGreaterThan`
  - `IsGreaterThanOrEqualTo`
  - `IsLessThan`
  - `IsLessThanOrEqualTo`
  - `IsIn`
  - `IsNotIn`

- Logical:
  - `And`
  - `Not`
  - `Or`

These operations are supported by most embedding stores and serve as a
good starting point. However, the list of operations will expand over
time to include other operations (e.g., `Contains`) supported by
embedding stores.

Currently, the DSL looks like this:
```java
Filter onlyDocs = metadataKey("type").isEqualTo("documentation");

Filter docsAndTutorialsAfter2020 = metadataKey("type").isIn("documentation", "tutorial").and(metadataKey("year").isGreaterThan(2020));
// or
Filter docsAndTutorialsAfter2020 = and(
    metadataKey("type").isIn("documentation", "tutorial"),
    metadataKey("year").isGreaterThan(2020)
);
```

## Filter expression as a `String`
Filter expression can also be specified as a `String`. This might be
necessary, for example, if the filter expression is generated
dynamically by the application or by the LLM (as in [self
querying](https://python.langchain.com/docs/modules/data_connection/retrievers/self_query/)).

This PR introduces a `FilterParser` interface with a simple `Filter
parse(String)` API, allowing for future support of multiple syntaxes (if
this will be required).

For the out-of-the-box filter syntax, ANSI SQL's `WHERE` clause is
proposed as a suitable candidate for several reasons:
- SQL is well-known among Java developers
- There is extensive tooling available for SQL (e.g., parsers)
- LLMs are pretty good at generating valid SQL, as there are tons of SQL
queries on the internet, which are included in the LLM training
datasets. There are also specialized LLMs that are trained for
text-to-SQL task, such as [SQLCoder](https://huggingface.co/defog).

The downside is that SQL's `WHERE` clause might not support all
operations and data types that could be supported in the future by
various embedding stores. In such case, we could extend it to a superset
of ANSI SQL `WHERE` syntax and/or provide an option to express filters
in the native syntax of the store.

An out-of-the-box implementation of the SQL `FilterParser` is provided
as a `SqlFilterParser` in a separate module
`langchain4j-embedding-store-filter-parser-sql`, using
[JSqlParser](https://github.com/JSQLParser/JSqlParser) under the hood.

`SqlFilterParser` can parse SQL "SELECT" (or just "WHERE" clause)
statement into a `Filter` object:
- `SELECT * FROM fake_table WHERE userId = '123-456'` ->
`metadataKey("userId").isEqualTo("123-456")`
- `userId = '123-456'`  ->  `metadataKey("userId").isEqualTo("123-456")`

It can also resolve `CURDATE()` and
`CURRENT_DATE`/`CURRENT_TIME`/`CURRENT_TIMESTAMP`:
`SELECT * FROM fake_table WHERE year = EXTRACT(YEAR FROM CURRENT_DATE`
-> `metadataKey("year").isEqualTo(LocalDate.now().getYear())`

## Changes in `Metadata` API
Until now, `Metadata` supported only `String` values. This PR expands
the list of supported value types to `Integer`, `Long`, `Float` and
`Double`. In the future, more types may be added (if needed).
The method `String get(String key)` will be deprecated later in favor
of:
- `String getString(String key)`
- `Integer getInteger(String key)`
- `Long getLong(String key)`
- etc

New overloaded `put(key, value)` methods are introduced to support more
value types:
- `put(String key, int value)`
- `put(String key, long value)`
- etc

## Changes in `EmbeddingStore` API
New method `search` is added that will become the main entry point for
search in the future. All `findRelevant` methods will be deprecated
later.
New `search` method accepts `EmbeddingSearchRequest` and returns
`EmbeddingSearchResult`.
`EmbeddingSearchRequest` contains all search criteria (e.g.
`maxResults`, `minScore`), including new `Filter`.
`EmbeddingSearchResult` contains a list of `EmbeddingMatch`.
```java
EmbeddingSearchResult search(EmbeddingSearchRequest request);
```

## Changes in `EmbeddingStoreContentRetriever` API
`EmbeddingStoreContentRetriever` can now be configured with a static
`filter` as well as dynamic `dynamicMaxResults`, `dynamicMinScore` and
`dynamicFilter` in the builder:
```java
ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                ...
                .maxResults(3)
                // or
                .dynamicMaxResults(query -> 3) // You can define maxResults dynamically. The value could, for example, depend on the query or the user associated with the query.
                ...
                .minScore(0.3)
                // or
                .dynamicMinScore(query -> 0.3)
                ...
                .filter(metadataKey("userId").isEqualTo("123-456")) // Assuming your TextSegments contain Metadata with key "userId"
                // or
                .dynamicFilter(query -> metadataKey("userId").isEqualTo(query.metadata().chatMemoryId().toString()))
                ...
                .build();
```
So now you can define `maxResults`, `minScore` and `filter` both
statically and dynamically (they can depend on the query, user, etc.).
These values will be propagated to the underlying `EmbeddingStore`.

##
["Self-querying"](https://python.langchain.com/docs/modules/data_connection/retrievers/self_query/)
This PR also introduces `LanguageModelSqlFilterBuilder` in
`langchain4j-embedding-store-filter-parser-sql` module which can be used
with `EmbeddingStoreContentRetriever`'s `dynamicFilter` to automatically
build a `Filter` object from the `Query` using language model and
`SqlFilterParser`.

For example:
```java
TextSegment groundhogDay = TextSegment.from("Groundhog Day", new Metadata().put("genre", "comedy").put("year", 1993));
TextSegment forrestGump = TextSegment.from("Forrest Gump", new Metadata().put("genre", "drama").put("year", 1994));
TextSegment dieHard = TextSegment.from("Die Hard", new Metadata().put("genre", "action").put("year", 1998));

// describe metadata keys as if they were columns in the SQL table
TableDefinition tableDefinition = TableDefinition.builder()
                .name("movies")
                .addColumn("genre", "VARCHAR", "one of [comedy, drama, action]")
                .addColumn("year", "INT")
                .build();

LanguageModelSqlFilterBuilder sqlFilterBuilder = new LanguageModelSqlFilterBuilder(model, tableDefinition);

ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .dynamicFilter(sqlFilterBuilder::build)
                .build();

String answer = assistant.answer("Recommend me a good drama from 90s"); // Forrest Gump
```

## Which embedding store integrations will support `Filter`?
In the long run, all (provided the embedding store itself supports it).
In the first iteration, I aim to add support to just a few:
- `InMemoryEmbeddingStore`
- Elasticsearch
- Milvus

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Introduced filters for checking key's value existence in a collection
for improved data handling.
- **Enhancements**
- Updated `InMemoryEmbeddingStoreTest` to extend a different class for
improved testing coverage and added a new test method.
- **Refactor**
- Made minor formatting adjustments in the assertion block for better
readability.
- **Documentation**
  - Updated class hierarchy information for clarity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-03-08 17:06:58 +01:00
Eddú Meléndez Gonzales 93403762da
Use Testcontainers Vector Database modules (#654)
Testcontainers 1.19.6 has released 4 new modules for vector databases
(ChromaDB, Milvus, Qdrant, Weaviate)
2024-02-22 15:19:26 +01:00
Eddú Meléndez Gonzales 3168433cb1
Enable Milvus IT by using Testcontainers (#314)
Currently, Milvus IT is disables because it requires a manual step
to run the compose file. Adding Testcontainers, the infrastructure
is in place to run the tests.
2023-12-04 17:54:54 +01:00
deep-learning-dynamo 7c5cade3c0 reducing duplication of *EmbeddingStoreIT 2023-11-18 20:02:21 +01:00
deep-learning-dynamo f8871900be *EmbeddingStoreTest -> *EmbeddingStoreIT 2023-11-10 13:48:32 +01:00
Heezer 50635b1499
support of database name configuration for Milvus (#233) 2023-10-17 20:52:12 +02:00
deep-learning-dynamo ea57a4e584 added notes that metadata is not stored in milvus, pinecone and vespa 2023-09-28 23:48:21 +02:00
deep-learning-dynamo bf1077c063 Milvus: return correct score 2023-09-28 18:18:17 +02:00
deep-learning-dynamo 7801eca701 Milvus: create collection and index automatically if it does not exist + refactoring 2023-09-26 15:51:23 +02:00
LangChain4j 93288a0826
Remove dynamic loading from Milvus (#188) 2023-09-21 12:16:43 +02:00
LangChain4j 6f5845ff4e
Text segment improvements (#134) 2023-08-28 20:35:57 +02:00
Iurii Koval ec4a673b52
Add Milvus support (#58)
Authored-by: iurii.koval <koval.iurii@protonmail.com>
2023-08-18 20:38:45 +02:00