Skip to content

Commit 7426f2e

Browse files
Merge branch 'main' into support-embedding-types
Signed-off-by: Martin Gaievski <gaievski@amazon.com>
2 parents 744bafb + c36ca15 commit 7426f2e

File tree

49 files changed

+381
-344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+381
-344
lines changed

.github/workflows/CI.yml

-22
Original file line numberDiff line numberDiff line change
@@ -117,28 +117,6 @@ jobs:
117117
name: coverage-report-${{ matrix.os }}-${{ matrix.java }}
118118
path: ./jacocoTestReport.xml
119119

120-
Precommit-neural-search-windows:
121-
strategy:
122-
matrix:
123-
java: [21, 23]
124-
os: [windows-latest]
125-
126-
name: Pre-commit Windows
127-
runs-on: ${{ matrix.os }}
128-
129-
steps:
130-
- uses: actions/checkout@v4
131-
132-
- name: Setup Java ${{ matrix.java }}
133-
uses: actions/setup-java@v4
134-
with:
135-
distribution: 'temurin'
136-
java-version: ${{ matrix.java }}
137-
138-
- name: Run build
139-
run: |
140-
./gradlew precommit --parallel
141-
142120
Precommit-codecov:
143121
needs: Precommit-neural-search-linux
144122
strategy:

.github/workflows/backwards_compatibility_tests_workflow.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
Restart-Upgrade-BWCTests-NeuralSearch:
1414
strategy:
1515
matrix:
16-
java: [21, 23]
17-
os: [ubuntu-latest,windows-latest]
18-
bwc_version : ["2.9.0","2.10.0","2.11.0","2.12.0","2.13.0","2.14.0","2.15.0","2.16.0","2.17.0","2.18.0","2.19.0-SNAPSHOT"]
16+
java: [ 21, 23 ]
17+
os: [ubuntu-latest]
18+
bwc_version : ["2.9.0","2.10.0","2.11.0","2.12.0","2.13.0","2.14.0","2.15.0","2.16.0","2.17.0","2.18.0","2.19.0","2.20.0-SNAPSHOT"]
1919
opensearch_version : [ "3.0.0-SNAPSHOT" ]
2020

2121
name: NeuralSearch Restart-Upgrade BWC Tests
@@ -42,7 +42,7 @@ jobs:
4242
matrix:
4343
java: [21, 23]
4444
os: [ubuntu-latest,windows-latest]
45-
bwc_version: [ "2.19.0-SNAPSHOT" ]
45+
bwc_version: [ "2.20.0-SNAPSHOT" ]
4646
opensearch_version: [ "3.0.0-SNAPSHOT" ]
4747

4848
name: NeuralSearch Rolling-Upgrade BWC Tests

.github/workflows/test_aggregations.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ jobs:
5454
Check-neural-search-windows:
5555
strategy:
5656
matrix:
57-
java: [21, 23]
57+
java: [23]
5858
os: [windows-latest]
5959

6060
name: Integ Tests Windows

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
## [Unreleased 3.0](https://github.com/opensearch-project/neural-search/compare/2.x...HEAD)
77
### Features
88
### Enhancements
9-
- Set neural-search plugin 3.0.0 baseline JDK version to JDK-2 ([#838](https://github.com/opensearch-project/neural-search/pull/838))
9+
- Set neural-search plugin 3.0.0 baseline JDK version to JDK-21 ([#838](https://github.com/opensearch-project/neural-search/pull/838))
1010
- Support different embedding types in model's response ([#1007](https://github.com/opensearch-project/neural-search/pull/1007))
1111
### Bug Fixes
1212
### Infrastructure
13+
- [3.0] Update neural-search for OpenSearch 3.0 compatibility ([#1141](https://github.com/opensearch-project/neural-search/pull/1141))
1314
### Documentation
1415
### Maintenance
1516
### Refactoring

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import java.util.concurrent.Callable
1414

1515
buildscript {
1616
ext {
17-
opensearch_version = System.getProperty("opensearch.version", "3.0.0-SNAPSHOT")
18-
buildVersionQualifier = System.getProperty("build.version_qualifier", "")
17+
opensearch_version = System.getProperty("opensearch.version", "3.0.0-alpha1-SNAPSHOT")
18+
buildVersionQualifier = System.getProperty("build.version_qualifier", "alpha1")
1919
isSnapshot = "true" == System.getProperty("build.snapshot", "true")
2020
version_tokens = opensearch_version.tokenize('-')
2121
opensearch_build = version_tokens[0] + '.0'

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# https://github.com/opensearch-project/OpenSearch/blob/main/libs/core/src/main/java/org/opensearch/Version.java .
88
# Wired compatibility of OpenSearch works like 3.x version is compatible with 2.(latest-major) version.
99
# Therefore, to run rolling-upgrade BWC Test on local machine the BWC version here should be set 2.(latest-major).
10-
systemProp.bwc.version=2.19.0-SNAPSHOT
10+
systemProp.bwc.version=2.20.0-SNAPSHOT
1111
systemProp.bwc.bundle.version=2.19.0
1212

1313
# For fixing Spotless check with Java 17

gradle/wrapper/gradle-wrapper.properties

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#
2+
# Copyright OpenSearch Contributors
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
16
distributionBase=GRADLE_USER_HOME
27
distributionPath=wrapper/dists
38
distributionSha256Sum=2ab88d6de2c23e6adae7363ae6e29cbdd2a709e992929b48b6530fd0c7133bd6

gradlew

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#!/bin/sh
2+
#
3+
# Copyright OpenSearch Contributors
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
26

37
#
48
# Copyright © 2015-2021 the original authors.

gradlew.bat

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
@rem
2+
@rem Copyright OpenSearch Contributors
3+
@rem SPDX-License-Identifier: Apache-2.0
4+
@rem
25
@rem Copyright 2015 the original author or authors.
36
@rem
47
@rem Licensed under the Apache License, Version 2.0 (the "License");

qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/rolling/AbstractRollingUpgradeTestCase.java

+25
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import java.nio.file.Path;
99
import java.util.Locale;
1010
import java.util.Optional;
11+
import java.util.Set;
12+
1113
import org.junit.Before;
1214
import org.opensearch.common.settings.Settings;
15+
import org.opensearch.ml.common.model.MLModelState;
1316
import org.opensearch.neuralsearch.BaseNeuralSearchIT;
1417
import static org.opensearch.neuralsearch.util.TestUtils.NEURAL_SEARCH_BWC_PREFIX;
1518
import static org.opensearch.neuralsearch.util.TestUtils.OLD_CLUSTER;
@@ -23,6 +26,8 @@
2326

2427
public abstract class AbstractRollingUpgradeTestCase extends BaseNeuralSearchIT {
2528

29+
private static final Set<MLModelState> READY_FOR_INFERENCE_STATES = Set.of(MLModelState.LOADED, MLModelState.DEPLOYED);
30+
2631
@Before
2732
protected String getIndexNameForTest() {
2833
// Creating index name by concatenating "neural-bwc-" prefix with test method name
@@ -159,4 +164,24 @@ protected void createPipelineForTextChunkingProcessor(String pipelineName) throw
159164
);
160165
createPipelineProcessor(requestBody, pipelineName, "", null);
161166
}
167+
168+
protected boolean isModelReadyForInference(final MLModelState mlModelState) throws Exception {
169+
return READY_FOR_INFERENCE_STATES.contains(mlModelState);
170+
}
171+
172+
protected void waitForModelToLoad(String modelId) throws Exception {
173+
int maxAttempts = 30; // Maximum number of attempts
174+
int waitTimeInSeconds = 2; // Time to wait between attempts
175+
176+
for (int attempt = 0; attempt < maxAttempts; attempt++) {
177+
MLModelState state = getModelState(modelId);
178+
if (isModelReadyForInference(state)) {
179+
logger.info("Model {} is now loaded after {} attempts", modelId, attempt + 1);
180+
return;
181+
}
182+
logger.info("Waiting for model {} to load. Current state: {}. Attempt {}/{}", modelId, state, attempt + 1, maxAttempts);
183+
Thread.sleep(waitTimeInSeconds * 1000);
184+
}
185+
throw new RuntimeException("Model " + modelId + " failed to load after " + maxAttempts + " attempts");
186+
}
162187
}

qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/rolling/BatchIngestionIT.java

-16
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,4 @@ public void testBatchIngestion_SparseEncodingProcessor_E2EFlow() throws Exceptio
9999
throw new IllegalStateException("Unexpected value: " + getClusterType());
100100
}
101101
}
102-
103-
private void waitForModelToLoad(String modelId) throws Exception {
104-
int maxAttempts = 30; // Maximum number of attempts
105-
int waitTimeInSeconds = 2; // Time to wait between attempts
106-
107-
for (int attempt = 0; attempt < maxAttempts; attempt++) {
108-
MLModelState state = getModelState(modelId);
109-
if (state == MLModelState.LOADED) {
110-
logger.info("Model {} is now loaded after {} attempts", modelId, attempt + 1);
111-
return;
112-
}
113-
logger.info("Waiting for model {} to load. Current state: {}. Attempt {}/{}", modelId, state, attempt + 1, maxAttempts);
114-
Thread.sleep(waitTimeInSeconds * 1000);
115-
}
116-
throw new RuntimeException("Model " + modelId + " failed to load after " + maxAttempts + " attempts");
117-
}
118102
}

src/main/java/org/opensearch/neuralsearch/plugin/NeuralSearch.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import java.util.Optional;
1515
import java.util.function.Supplier;
1616

17-
import org.opensearch.client.Client;
17+
import org.opensearch.transport.client.Client;
1818
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
1919
import org.opensearch.cluster.service.ClusterService;
2020
import org.opensearch.common.settings.Setting;

src/main/java/org/opensearch/neuralsearch/processor/NormalizationProcessorWorkflow.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ private List<CompoundTopDocs> getCompoundTopDocs(CombineScoresDto combineScoresD
242242
* @return max score
243243
*/
244244
private float maxScoreForShard(CompoundTopDocs updatedTopDocs, boolean isSortEnabled) {
245-
if (updatedTopDocs.getTotalHits().value == 0 || updatedTopDocs.getScoreDocs().isEmpty()) {
245+
if (updatedTopDocs.getTotalHits().value() == 0 || updatedTopDocs.getScoreDocs().isEmpty()) {
246246
return MAX_SCORE_WHEN_NO_HITS_FOUND;
247247
}
248248
if (isSortEnabled) {

src/main/java/org/opensearch/neuralsearch/processor/combination/ScoreCombiner.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private void combineShardScores(
8181
final CompoundTopDocs compoundQueryTopDocs,
8282
final Sort sort
8383
) {
84-
if (Objects.isNull(compoundQueryTopDocs) || compoundQueryTopDocs.getTotalHits().value == 0) {
84+
if (Objects.isNull(compoundQueryTopDocs) || compoundQueryTopDocs.getTotalHits().value() == 0) {
8585
return;
8686
}
8787
List<TopDocs> topDocsPerSubQuery = compoundQueryTopDocs.getTopDocs();
@@ -292,7 +292,7 @@ private void updateQueryTopDocsWithCombinedScores(
292292
boolean isSortingEnabled
293293
) {
294294
// - max number of hits will be the same which are passed from QueryPhase
295-
long maxHits = compoundQueryTopDocs.getTotalHits().value;
295+
long maxHits = compoundQueryTopDocs.getTotalHits().value();
296296
// - update query search results with normalized scores
297297
compoundQueryTopDocs.setScoreDocs(
298298
getCombinedScoreDocs(
@@ -309,7 +309,7 @@ private void updateQueryTopDocsWithCombinedScores(
309309

310310
private TotalHits getTotalHits(final List<TopDocs> topDocsPerSubQuery, final long maxHits) {
311311
TotalHits.Relation totalHits = TotalHits.Relation.EQUAL_TO;
312-
if (topDocsPerSubQuery.stream().anyMatch(topDocs -> topDocs.totalHits.relation == TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO)) {
312+
if (topDocsPerSubQuery.stream().anyMatch(topDocs -> topDocs.totalHits.relation() == TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO)) {
313313
totalHits = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
314314
}
315315
return new TotalHits(maxHits, totalHits);
@@ -343,7 +343,7 @@ private List<ExplanationDetails> explainByShard(
343343
final CompoundTopDocs compoundQueryTopDocs,
344344
final Sort sort
345345
) {
346-
if (Objects.isNull(compoundQueryTopDocs) || compoundQueryTopDocs.getTotalHits().value == 0) {
346+
if (Objects.isNull(compoundQueryTopDocs) || compoundQueryTopDocs.getTotalHits().value() == 0) {
347347
return List.of();
348348
}
349349
// create map of normalized scores results returned from the single shard

src/main/java/org/opensearch/neuralsearch/processor/rerank/RescoringRerankProcessor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public void rerank(
5959
final ActionListener<SearchResponse> listener
6060
) {
6161
try {
62-
if (searchResponse.getHits().getTotalHits().value == 0) {
62+
if (searchResponse.getHits().getTotalHits().value() == 0) {
6363
listener.onResponse(searchResponse);
6464
return;
6565
}

src/main/java/org/opensearch/neuralsearch/query/HybridQuery.java

+23-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.Map;
1515
import java.util.Objects;
1616
import java.util.concurrent.Callable;
17+
import java.util.stream.Collectors;
1718

1819
import org.apache.lucene.search.BooleanClause;
1920
import org.apache.lucene.search.BooleanQuery;
@@ -42,6 +43,26 @@ public final class HybridQuery extends Query implements Iterable<Query> {
4243
* @param filterQueries list of filters that will be applied to each sub query. Each filter from the list is added as bool "filter" clause. If this is null sub queries will be executed as is
4344
*/
4445
public HybridQuery(final Collection<Query> subQueries, final List<Query> filterQueries, final HybridQueryContext hybridQueryContext) {
46+
this(
47+
subQueries,
48+
hybridQueryContext,
49+
filterQueries == null
50+
? null
51+
: filterQueries.stream().map(query -> new BooleanClause(query, BooleanClause.Occur.FILTER)).collect(Collectors.toList())
52+
);
53+
}
54+
55+
/**
56+
* Create new instance of hybrid query object based on collection of sub queries and boolean clauses that are used as filters for each sub-query
57+
* @param subQueries
58+
* @param hybridQueryContext
59+
* @param booleanClauses
60+
*/
61+
public HybridQuery(
62+
final Collection<Query> subQueries,
63+
final HybridQueryContext hybridQueryContext,
64+
final List<BooleanClause> booleanClauses
65+
) {
4566
Objects.requireNonNull(subQueries, "collection of queries must not be null");
4667
if (subQueries.isEmpty()) {
4768
throw new IllegalArgumentException("collection of queries must not be empty");
@@ -50,14 +71,14 @@ public HybridQuery(final Collection<Query> subQueries, final List<Query> filterQ
5071
if (Objects.nonNull(paginationDepth) && paginationDepth == 0) {
5172
throw new IllegalArgumentException("pagination_depth must not be zero");
5273
}
53-
if (Objects.isNull(filterQueries) || filterQueries.isEmpty()) {
74+
if (Objects.isNull(booleanClauses) || booleanClauses.isEmpty()) {
5475
this.subQueries = new ArrayList<>(subQueries);
5576
} else {
5677
List<Query> modifiedSubQueries = new ArrayList<>();
5778
for (Query subQuery : subQueries) {
5879
BooleanQuery.Builder builder = new BooleanQuery.Builder();
5980
builder.add(subQuery, BooleanClause.Occur.MUST);
60-
filterQueries.forEach(filterQuery -> builder.add(filterQuery, BooleanClause.Occur.FILTER));
81+
booleanClauses.forEach(filterQuery -> builder.add(booleanClauses));
6182
modifiedSubQueries.add(builder.build());
6283
}
6384
this.subQueries = modifiedSubQueries;

src/main/java/org/opensearch/neuralsearch/query/HybridQueryScorer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public HybridQueryScorer(final Weight weight, final List<Scorer> subScorers) thr
4949
}
5050

5151
HybridQueryScorer(final Weight weight, final List<Scorer> subScorers, final ScoreMode scoreMode) throws IOException {
52-
super(weight);
52+
super();
5353
this.subScorers = Collections.unmodifiableList(subScorers);
5454
this.numSubqueries = subScorers.size();
5555
this.subScorersPQ = initializeSubScorersPQ();

src/main/java/org/opensearch/neuralsearch/query/HybridQueryWeight.java

-18
Original file line numberDiff line numberDiff line change
@@ -109,24 +109,6 @@ private Void addScoreSupplier(Weight weight, HybridQueryExecutorCollector<LeafRe
109109
return null;
110110
}
111111

112-
/**
113-
* Create the scorer used to score our associated Query
114-
*
115-
* @param context the {@link LeafReaderContext} for which to return the
116-
* {@link Scorer}.
117-
* @return scorer of hybrid query that contains scorers of each sub-query, null if there are no matches in any sub-query
118-
* @throws IOException
119-
*/
120-
@Override
121-
public Scorer scorer(LeafReaderContext context) throws IOException {
122-
ScorerSupplier supplier = scorerSupplier(context);
123-
if (supplier == null) {
124-
return null;
125-
}
126-
supplier.setTopLevelScoringClause();
127-
return supplier.get(Long.MAX_VALUE);
128-
}
129-
130112
/**
131113
* Check if weight object can be cached
132114
*

src/main/java/org/opensearch/neuralsearch/query/NeuralKNNQuery.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package org.opensearch.neuralsearch.query;
66

77
import lombok.Getter;
8-
import org.apache.lucene.index.IndexReader;
98
import org.apache.lucene.search.IndexSearcher;
109
import org.apache.lucene.search.Query;
1110
import org.apache.lucene.search.QueryVisitor;
@@ -45,8 +44,8 @@ public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float bo
4544
}
4645

4746
@Override
48-
public Query rewrite(IndexReader reader) throws IOException {
49-
Query rewritten = knnQuery.rewrite(reader);
47+
public Query rewrite(IndexSearcher indexSearcher) throws IOException {
48+
Query rewritten = knnQuery.rewrite(indexSearcher);
5049
if (rewritten == knnQuery) {
5150
return this;
5251
}

src/main/java/org/opensearch/neuralsearch/query/NeuralSparseQueryBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.apache.lucene.search.BooleanQuery;
2222
import org.apache.lucene.search.Query;
2323
import org.opensearch.Version;
24-
import org.opensearch.client.Client;
24+
import org.opensearch.transport.client.Client;
2525
import org.opensearch.common.SetOnce;
2626
import org.opensearch.common.collect.Tuple;
2727
import org.opensearch.core.ParseField;

src/main/java/org/opensearch/neuralsearch/search/HybridDisiWrapper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class HybridDisiWrapper extends DisiWrapper {
1717
private final int subQueryIndex;
1818

1919
public HybridDisiWrapper(Scorer scorer, int subQueryIndex) {
20-
super(scorer);
20+
super(scorer, false);
2121
this.subQueryIndex = subQueryIndex;
2222
}
2323
}

src/main/java/org/opensearch/neuralsearch/search/collector/HybridTopFieldDocSortCollector.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,13 @@ private HybridQueryScorer getHybridQueryScorer(final Scorable scorer) throws IOE
166166
return (HybridQueryScorer) scorer;
167167
}
168168
for (Scorable.ChildScorable childScorable : scorer.getChildren()) {
169-
HybridQueryScorer hybridQueryScorer = getHybridQueryScorer(childScorable.child);
169+
HybridQueryScorer hybridQueryScorer = getHybridQueryScorer(childScorable.child());
170170
if (Objects.nonNull(hybridQueryScorer)) {
171171
log.debug(
172172
String.format(
173173
Locale.ROOT,
174174
"found hybrid query scorer, it's child of scorer %s",
175-
childScorable.child.getClass().getSimpleName()
175+
childScorable.child().getClass().getSimpleName()
176176
)
177177
);
178178
return hybridQueryScorer;
@@ -289,7 +289,7 @@ private void initializeLeafFieldComparators(LeafReaderContext context, int subQu
289289
private void initializeComparators(LeafReaderContext context, int subQueryNumber) throws IOException {
290290
// as all segments are sorted in the same way, enough to check only the 1st segment for indexSort
291291
if (searchSortPartOfIndexSort == null) {
292-
Sort indexSort = context.reader().getMetaData().getSort();
292+
Sort indexSort = context.reader().getMetaData().sort();
293293
searchSortPartOfIndexSort = canEarlyTerminate(sort, indexSort);
294294
if (searchSortPartOfIndexSort) {
295295
firstComparator.disableSkipping();

0 commit comments

Comments
 (0)