Skip to content

Commit

Permalink
Support multiple indices in PPL and SQL
Browse files Browse the repository at this point in the history
Signed-off-by: penghuo <[email protected]>
  • Loading branch information
penghuo committed Feb 2, 2022
1 parent 91e86b8 commit 4c4fa10
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 33 deletions.
19 changes: 17 additions & 2 deletions core/src/main/java/org/opensearch/sql/ast/tree/Relation.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
package org.opensearch.sql.ast.tree;

import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,7 +25,18 @@
@EqualsAndHashCode(callSuper = false)
@RequiredArgsConstructor
public class Relation extends UnresolvedPlan {
private final UnresolvedExpression tableName;
private static final String COMMA = ",";

private final List<UnresolvedExpression> tableName;

public Relation(UnresolvedExpression tableName) {
this(tableName, null);
}

public Relation(UnresolvedExpression tableName, String alias) {
this.tableName = Arrays.asList(tableName);
this.alias = alias;
}

/**
* Optional alias name for the relation.
Expand All @@ -36,7 +49,9 @@ public class Relation extends UnresolvedPlan {
* @return table name
*/
public String getTableName() {
return tableName.toString();
return tableName.stream()
.map(UnresolvedExpression::toString)
.collect(Collectors.joining(COMMA));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/


package org.opensearch.sql.ast.tree;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.opensearch.sql.ast.dsl.AstDSL.qualifiedName;

import java.util.Arrays;
import org.junit.jupiter.api.Test;

class RelationTest {
Expand All @@ -26,4 +26,9 @@ void should_return_alias_if_aliased() {
assertEquals("t", relation.getTableNameOrAlias());
}

@Test
void comma_seperated_index_return_concat_table_names() {
Relation relation = new Relation(Arrays.asList(qualifiedName("test1"), qualifiedName("test2")));
assertEquals("test1,test2", relation.getTableNameOrAlias());
}
}
38 changes: 37 additions & 1 deletion docs/user/general/identifiers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Examples

Here are examples for using index pattern directly without quotes::

os> SELECT * FROM *cc*nt*;
os> SELECT * FROM *cc*nts;
fetched rows / total rows = 4/4
+------------------+-------------+----------------------+-----------+----------+--------+------------+---------+-------+-----------------------+------------+
| account_number | firstname | address | balance | gender | city | employer | state | age | email | lastname |
Expand Down Expand Up @@ -140,3 +140,39 @@ The second example is to show a field name qualified by index alias specified. S
+--------+-------+--------------------+

Note that in both examples above, the qualifier is removed in response. This happens only when identifiers selected is a simple field name. In other cases, expressions rather than an atom field, the column name in response is exactly the same as the text in ``SELECT``clause.
Multiple Indices
================
Description
-----------
To query multiple indices, you could
1. Include ``*`` in index name, this is an index pattern for wildcard match.
2. Delimited multiple indices and seperated them by ``,``. Note: no space allowed between each index.


Examples
---------

Query wildcard indices::

os> SELECT count(*) as cnt FROM acc*;
fetched rows / total rows = 1/1
+-------+
| cnt |
|-------|
| 5 |
+-------+


Query delimited multiple indices seperated by ``,``::

os> SELECT count(*) as cnt FROM `accounts,account2`;
fetched rows / total rows = 1/1
+-------+
| cnt |
|-------|
| 5 |
+-------+
49 changes: 48 additions & 1 deletion docs/user/ppl/general/identifiers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,51 @@ Identifiers are treated in case sensitive manner. So it must be exactly same as
Examples
--------

For example, if you run ``source=Accounts``, it will end up with an index not found exception from our plugin because the actual index name is under lower case.
For example, if you run ``source=Accounts``, it will end up with an index not found exception from our plugin because the actual index name is under lower case.

Multiple Indices
================

Description
-----------

To query multiple indices, you could

1. Include ``*`` in index name, this is an index pattern for wildcard match.
2. Include multiple indices and seperated them by ``,``.
3. Delimited multiple indices and seperated them by ``,``. Note: no space allowed between each index.


Examples
---------

Query wildcard indices::

os> source=acc* | stats count();
fetched rows / total rows = 1/1
+-----------+
| count() |
|-----------|
| 5 |
+-----------+

Query multiple indices seperated by ``,``::

os> source=accounts, account2 | stats count();
fetched rows / total rows = 1/1
+-----------+
| count() |
|-----------|
| 5 |
+-----------+

Query delimited multiple indices seperated by ``,``::

os> source=`accounts,account2` | stats count();
fetched rows / total rows = 1/1
+-----------+
| count() |
|-----------|
| 5 |
+-----------+

1 change: 1 addition & 0 deletions doctest/test_data/account2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"account_number":2}
4 changes: 3 additions & 1 deletion doctest/test_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
ACCOUNTS = "accounts"
EMPLOYEES = "employees"
PEOPLE = "people"
ACCOUNT2 = "account2"


class DocTestConnection(OpenSearchConnection):
Expand Down Expand Up @@ -84,6 +85,7 @@ def set_up_test_indices(test):
set_up(test)
load_file("accounts.json", index_name=ACCOUNTS)
load_file("people.json", index_name=PEOPLE)
load_file("account2.json", index_name=ACCOUNT2)


def load_file(filename, index_name):
Expand Down Expand Up @@ -112,7 +114,7 @@ def set_up(test):

def tear_down(test):
# drop leftover tables after each test
test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE], ignore_unavailable=True)
test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2], ignore_unavailable=True)


docsuite = partial(doctest.DocFileSuite,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public interface OpenSearchClient {
* @param indexExpression index expression
* @return index mapping(s) from index name to its mapping
*/
Map<String, IndexMapping> getIndexMappings(String indexExpression);
Map<String, IndexMapping> getIndexMappings(String... indexExpression);

/**
* Perform search query in the search request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ public OpenSearchNodeClient(ClusterService clusterService,
* thrown if no index matched.
*/
@Override
public Map<String, IndexMapping> getIndexMappings(String indexExpression) {
public Map<String, IndexMapping> getIndexMappings(String... indexExpression) {
try {
ClusterState state = clusterService.state();
String[] concreteIndices = resolveIndexExpression(state, new String[] {indexExpression});
String[] concreteIndices = resolveIndexExpression(state, indexExpression);

return populateIndexMappings(
state.metadata().findMappings(concreteIndices, ALL_TYPES, ALL_FIELDS));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class OpenSearchRestClient implements OpenSearchClient {
private final RestHighLevelClient client;

@Override
public Map<String, IndexMapping> getIndexMappings(String indexExpression) {
public Map<String, IndexMapping> getIndexMappings(String... indexExpression) {
GetMappingsRequest request = new GetMappingsRequest().indices(indexExpression);
try {
GetMappingsResponse response = client.indices().getMapping(request, RequestOptions.DEFAULT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ public class OpenSearchQueryRequest implements OpenSearchRequest {
public static final TimeValue DEFAULT_QUERY_TIMEOUT = TimeValue.timeValueMinutes(1L);

/**
* Index name.
* {@link OpenSearchRequest.IndexName}.
*/
private final String indexName;
private final IndexName indexName;

/**
* Search request source builder.
Expand All @@ -65,6 +65,14 @@ public class OpenSearchQueryRequest implements OpenSearchRequest {
*/
public OpenSearchQueryRequest(String indexName, int size,
OpenSearchExprValueFactory factory) {
this(new IndexName(indexName), size, factory);
}

/**
* Constructor of ElasticsearchQueryRequest.
*/
public OpenSearchQueryRequest(IndexName indexName, int size,
OpenSearchExprValueFactory factory) {
this.indexName = indexName;
this.sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(0);
Expand Down Expand Up @@ -97,7 +105,7 @@ public void clean(Consumer<String> cleanAction) {
@VisibleForTesting
protected SearchRequest searchRequest() {
return new SearchRequest()
.indices(indexName)
.indices(indexName.getIndexNames())
.source(sourceBuilder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.function.Consumer;
import java.util.function.Function;
import lombok.EqualsAndHashCode;
import org.opensearch.action.search.SearchRequest;
import org.opensearch.action.search.SearchResponse;
import org.opensearch.action.search.SearchScrollRequest;
Expand All @@ -19,7 +20,6 @@
* OpenSearch search request.
*/
public interface OpenSearchRequest {

/**
* Apply the search action or scroll action on request based on context.
*
Expand Down Expand Up @@ -49,4 +49,28 @@ OpenSearchResponse search(Function<SearchRequest, SearchResponse> searchAction,
* @return ElasticsearchExprValueFactory.
*/
OpenSearchExprValueFactory getExprValueFactory();

/**
* OpenSearch Index Name.
* Indices are seperated by ",".
*/
@EqualsAndHashCode
class IndexName {
private static final String COMMA = ",";

private final String[] indexNames;

public IndexName(String indexName) {
this.indexNames = indexName.split(COMMA);
}

public String[] getIndexNames() {
return indexNames;
}

@Override
public String toString() {
return String.join(COMMA, indexNames);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@
* Maintain scroll ID between calls to client search method
*/
@EqualsAndHashCode
@RequiredArgsConstructor
@Getter
@ToString
public class OpenSearchScrollRequest implements OpenSearchRequest {

/** Default scroll context timeout in minutes. */
public static final TimeValue DEFAULT_SCROLL_TIMEOUT = TimeValue.timeValueMinutes(1L);

/** Index name. */
private final String indexName;
/**
* {@link OpenSearchRequest.IndexName}.
*/
private final IndexName indexName;

/** Index name. */
@EqualsAndHashCode.Exclude
Expand All @@ -49,11 +50,20 @@ public class OpenSearchScrollRequest implements OpenSearchRequest {
* Scroll id which is set after first request issued. Because ElasticsearchClient is shared by
* multi-thread so this state has to be maintained here.
*/
@Setter private String scrollId;
@Setter
private String scrollId;

/** Search request source builder. */
private final SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

public OpenSearchScrollRequest(IndexName indexName, OpenSearchExprValueFactory exprValueFactory) {
this.indexName = indexName;
this.exprValueFactory = exprValueFactory;
}

public OpenSearchScrollRequest(String indexName, OpenSearchExprValueFactory exprValueFactory) {
this(new IndexName(indexName), exprValueFactory);
}

@Override
public OpenSearchResponse search(Function<SearchRequest, SearchResponse> searchAction,
Expand Down Expand Up @@ -87,7 +97,7 @@ public void clean(Consumer<String> cleanAction) {
*/
public SearchRequest searchRequest() {
return new SearchRequest()
.indices(indexName)
.indices(indexName.getIndexNames())
.scroll(DEFAULT_SCROLL_TIMEOUT)
.source(sourceBuilder);
}
Expand Down
Loading

0 comments on commit 4c4fa10

Please sign in to comment.