620993807f
## Issue Closes #2973. Also covers the metadata-mapping gap reported in #1098. ## Change `AzureAiSearchContentRetriever` and `AzureAiSearchEmbeddingStore` mapped segment metadata only from the nested complex `metadata` field this store writes itself. Against a pre-existing index whose fields live at the document root (`createOrUpdateIndex(false)`), those fields were unreachable, so results came back without their metadata. Add `metadataFieldNames` to both builders: an explicit allowlist of top-level index fields to expose as metadata. ```java ContentRetriever retriever = AzureAiSearchContentRetriever.builder() .endpoint(endpoint) .tokenCredential(tokenCredential) .indexName(indexName) .createOrUpdateIndex(false) .queryType(AzureAiSearchQueryType.FULL_TEXT) .metadataFieldNames(List.of("sourcepage", "weburl", "topic", "role")) .build(); ``` The listed fields are added to each result's `Metadata`, alongside the complex `metadata` field when present. Both classes share `getEmbeddingMatches`, so vector, full-text, hybrid and hybrid+reranking searches are all covered. A field is copied only when its value is a type `Metadata` supports (`String`, `Integer`, `Long`, `Float`, `Double`, or `UUID`), preserving the type; absent, `null` and other-typed values (such as the embedding vector) are skipped. An explicit allowlist keeps field selection predictable for bring-your-own indexes with arbitrary schemas. The default is an empty list, so existing behaviour is unchanged and the API change is additive only: the existing `metadataFrom(Object)` helper is kept as-is and the new behaviour is a delegating overload, so no revapi entries and no changes to the existing tests. The reformatting in `AzureAiSearchEmbeddingStore` is applied by Spotless (`ratchetFrom origin/main`). This PR configures metadata extraction only; the index's core ID, content, vector and semantic-search field names are unchanged (the broader field-name configuration in #1098 is out of scope here). ## Tests `AzureAiSearchEmbeddingStoreTest`, offline. The existing nested-metadata tests are kept as-is (the `metadataFrom(Object)` helper is unchanged); new tests cover the added overload: - allowlisted fields copied; `Integer` / `Double` / `UUID` values preserved with their type - absent / `null` / unsupported-typed / blank-name fields skipped - complex metadata and allowlisted fields merged; top-level field wins on key collision - the builder wires `metadataFieldNames` onto the store; `null` is treated as none ``` mvn -pl langchain4j-azure-ai-search verify Tests run: 34, Failures: 0, Errors: 0, Skipped: 0 (revapi + spotless green) ``` Core and main modules are green as well: ``` mvn -pl langchain4j-core,langchain4j test langchain4j-core: Tests run: 1247, Failures: 0, Errors: 0, Skipped: 5 langchain4j: Tests run: 1327, Failures: 0, Errors: 0, Skipped: 0 ``` ## 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 - [X] I have manually run all the unit and integration tests in the core and main modules, and they are all green - [X] I have added/updated the documentation - [ ] I have added an example in the examples repo (only for "big" features) - [ ] I have added/updated Spring Boot starter(s) (if applicable)