From 16b7c191824af1026100c1d21a1946464e3687d1 Mon Sep 17 00:00:00 2001
From: Dharin Shah <8616130+Dharin-shah@users.noreply.github.com>
Date: Sun, 17 Dec 2023 20:02:43 +0100
Subject: [PATCH 01/23] add support for scored named queries
Signed-off-by: Dharin Shah <8616130+Dharin-shah@users.noreply.github.com>
---
CHANGELOG.md | 1 +
.../core/common/io/stream/StreamInput.java | 71 +++++++++
.../resources/rest-api-spec/api/search.json | 5 +
.../test/search/350_matched_queries.yml | 103 ++++++++++++
.../fetch/subphase/MatchedQueriesIT.java | 96 ++++++-----
.../search/functionscore/QueryRescorerIT.java | 2 +-
.../rest/action/search/RestSearchAction.java | 6 +-
.../java/org/opensearch/search/SearchHit.java | 137 +++++++++-------
.../fetch/subphase/MatchedQueriesPhase.java | 32 ++--
.../common/io/stream/BytesStreamsTests.java | 34 ++++
.../org/opensearch/search/SearchHitTests.java | 150 +++++++++++++++++-
11 files changed, 522 insertions(+), 115 deletions(-)
create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/test/search/350_matched_queries.yml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c5ea3f83bffc7..e10e795fbec70 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -121,6 +121,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Adding slf4j license header to LoggerMessageFormat.java ([#11069](https://github.com/opensearch-project/OpenSearch/pull/11069))
- [BWC and API enforcement] Introduce checks for enforcing the API restrictions ([#11175](https://github.com/opensearch-project/OpenSearch/pull/11175))
- Create separate transport action for render search template action ([#11170](https://github.com/opensearch-project/OpenSearch/pull/11170))
+- Backwards compatible support for returning scores in matched queries ((https://github.com/opensearch-project/OpenSearch/pull/11549))
### Dependencies
- Bump Lucene from 9.7.0 to 9.8.0 ([10276](https://github.com/opensearch-project/OpenSearch/pull/10276))
diff --git a/libs/core/src/main/java/org/opensearch/core/common/io/stream/StreamInput.java b/libs/core/src/main/java/org/opensearch/core/common/io/stream/StreamInput.java
index 3e996bdee83a2..ac4e0f50b924c 100644
--- a/libs/core/src/main/java/org/opensearch/core/common/io/stream/StreamInput.java
+++ b/libs/core/src/main/java/org/opensearch/core/common/io/stream/StreamInput.java
@@ -632,6 +632,77 @@ public String[] readOptionalStringArray() throws IOException {
return null;
}
+
+ /**
+ * Reads an ordered {@link Map} from a data source using provided key and value readers.
+ *
+ * This method creates a `LinkedHashMap`, ensuring that the iteration order of the map
+ * matches the order in which the entries were read from the data source. It uses the
+ * `keyReader` and `valueReader` to read each key-value pair and constructs the map
+ * with an initial capacity optimized based on the expected size.
+ *
+ * Usage example:
+ *
+ * Map<Integer, String> orderedMap = readOrderedMap(StreamInput::readInteger, StreamInput::readString);
+ *
+ *
+ * @param keyReader The {@link Writeable.Reader} used to read the keys of the map.
+ * @param valueReader The {@link Writeable.Reader} used to read the values of the map.
+ * @return A {@link LinkedHashMap} containing the keys and values read from the data source.
+ * The map maintains the order in which keys and values were read.
+ * @throws IOException If an I/O error occurs during reading from the data source.
+ */
+ public Map readOrderedMap(Writeable.Reader keyReader, Writeable.Reader valueReader) throws IOException {
+ return readMap(keyReader, valueReader, (expectedSize) -> new LinkedHashMap<>(capacity(expectedSize)));
+ }
+
+ static int capacity(int expectedSize) {
+ assert expectedSize >= 0;
+ return expectedSize < 2 ? expectedSize + 1 : (int) (expectedSize / 0.75 + 1.0);
+ }
+
+ /**
+ * Reads a {@link Map} from a data source using provided key and value readers and a map constructor.
+ *
+ * This method is a flexible utility for reading a map from a data source, such as a file or network stream.
+ * It uses the provided `keyReader` and `valueReader` to read each key-value pair. The size of the map is
+ * determined first by reading the array size. A map constructor is also provided to create a map of the
+ * appropriate size, allowing for optimized performance based on the expected number of entries.
+ *
+ * If the read size is zero, an empty map is returned. Otherwise, the method iterates over the size,
+ * reading keys and values and adding them to the map.
+ *
+ * Usage example:
+ *
+ * Map<Integer, String> map = readMap(StreamInput::readInteger, StreamInput::readString, HashMap::new);
+ *
+ *
+ * Note: If the map is empty, an immutable empty map is returned. Otherwise, a mutable map is created.
+ *
+ * @param keyReader The {@link Writeable.Reader} used to read the keys of the map.
+ * @param valueReader The {@link Writeable.Reader} used to read the values of the map.
+ * @param constructor A function that takes an integer (the initial size) and returns a new map.
+ * This allows for the creation of a map with an initial capacity matching the
+ * expected size, optimizing performance.
+ * @return A {@link Map} containing the keys and values read from the data source. This map is either
+ * empty (and immutable) or mutable and filled with the read data.
+ * @throws IOException If an I/O error occurs during reading from the data source.
+ */
+ private Map readMap(Writeable.Reader keyReader, Writeable.Reader valueReader, IntFunction