-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Query Function As Query_string Function #143
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.sql; | ||
|
||
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_BEER; | ||
|
||
import java.io.IOException; | ||
import org.json.JSONObject; | ||
import org.junit.Test; | ||
import org.opensearch.sql.legacy.SQLIntegTestCase; | ||
|
||
public class QueryIT extends SQLIntegTestCase { | ||
GabeFernandez310 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@Override | ||
public void init() throws IOException { | ||
loadIndex(Index.BEER); | ||
} | ||
|
||
@Test | ||
public void all_fields_test() throws IOException { | ||
String query = "SELECT * FROM " | ||
+ TEST_INDEX_BEER + " WHERE query('*:taste')"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought the wildcard syntax doesn't work? Or does it work with just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought so too... I thought we determined that they didn't work when we had our 1:1. I played around with it trying different combinations... The following all seem to work when passed in as the query for query_string:
I tried these according to this documentation for Lucene, but it doesn't seem to follow it exactly since it also allows There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added Unit Tests in f2d77c6 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was more asking about the field name ( Honestly, the checks are handled by OpenSearch not us... so what additional tests are going to do is test another system. We can consider covering some of the general cases, but we do not need to be exhaustive here. |
||
JSONObject result = executeJdbcRequest(query); | ||
assertEquals(16, result.getInt("total")); | ||
} | ||
|
||
@Test | ||
public void mandatory_params_test() throws IOException { | ||
forestmvey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
String query = "SELECT Id FROM " | ||
+ TEST_INDEX_BEER + " WHERE query('Tags:taste OR Body:taste')"; | ||
JSONObject result = executeJdbcRequest(query); | ||
assertEquals(16, result.getInt("total")); | ||
} | ||
|
||
@Test | ||
public void all_params_test() throws IOException { | ||
String query = "SELECT Id FROM " + TEST_INDEX_BEER | ||
+ " WHERE query('Tags:taste', escape=false," | ||
+ "allow_leading_wildcard=true, enable_position_increments=true," | ||
+ "fuzziness= 1, fuzzy_rewrite='constant_score', max_determinized_states = 10000," | ||
+ "analyzer='standard', analyze_wildcard = false, quote_field_suffix = '.exact'," | ||
+ "auto_generate_synonyms_phrase_query=true, boost = 0.77," | ||
+ "quote_analyzer='standard', phrase_slop=0, rewrite='constant_score', type='best_fields'," | ||
+ "tie_breaker=0.3, time_zone='Canada/Pacific', default_operator='or'," | ||
+ "fuzzy_transpositions = false, lenient = true, fuzzy_max_expansions = 25," | ||
+ "minimum_should_match = '2<-25% 9<-3', fuzzy_prefix_length = 7);"; | ||
JSONObject result = executeJdbcRequest(query); | ||
assertEquals(8, result.getInt("total")); | ||
} | ||
|
||
@Test | ||
public void wildcard_test() throws IOException { | ||
String query1 = "SELECT Id FROM " | ||
+ TEST_INDEX_BEER + " WHERE query('Tags:taste')"; | ||
JSONObject result1 = executeJdbcRequest(query1); | ||
String query2 = "SELECT Id FROM " | ||
+ TEST_INDEX_BEER + " WHERE query('*:taste')"; | ||
JSONObject result2 = executeJdbcRequest(query2); | ||
assertNotEquals(result2.getInt("total"), result1.getInt("total")); | ||
|
||
String query3 = "SELECT Id FROM " + TEST_INDEX_BEER | ||
+ " WHERE query('Tags:tas*');"; | ||
JSONObject result3 = executeJdbcRequest(query3); | ||
assertEquals(8, result3.getInt("total")); | ||
|
||
String query4 = "SELECT Id FROM " + TEST_INDEX_BEER | ||
+ " WHERE query('Tags:tas?e');"; | ||
JSONObject result4 = executeJdbcRequest(query3); | ||
assertEquals(8, result4.getInt("total")); | ||
} | ||
|
||
@Test | ||
public void query_string_and_query_return_the_same_results_test() throws IOException { | ||
String query1 = "SELECT Id FROM " | ||
+ TEST_INDEX_BEER + " WHERE query('Tags:taste')"; | ||
JSONObject result1 = executeJdbcRequest(query1); | ||
String query2 = "SELECT Id FROM " | ||
+ TEST_INDEX_BEER + " WHERE query_string(['Tags'],'taste')"; | ||
JSONObject result2 = executeJdbcRequest(query2); | ||
assertEquals(result2.getInt("total"), result1.getInt("total")); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.opensearch.storage.script.filter.lucene.relevance; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.stream.Collectors; | ||
import org.opensearch.index.query.QueryBuilder; | ||
import org.opensearch.sql.common.antlr.SyntaxCheckException; | ||
import org.opensearch.sql.exception.SemanticCheckException; | ||
import org.opensearch.sql.expression.FunctionExpression; | ||
import org.opensearch.sql.expression.NamedArgumentExpression; | ||
|
||
/** | ||
* Base class to represent relevance queries that search multiple fields. | ||
* | ||
* @param <T> The builder class for the OpenSearch query. | ||
*/ | ||
abstract class NoFieldQuery<T extends QueryBuilder> extends RelevanceQuery<T> { | ||
public NoFieldQuery(Map<String, QueryBuilderStep<T>> queryBuildActions) { | ||
super(queryBuildActions); | ||
} | ||
|
||
@Override | ||
protected void ignoreArguments(List<NamedArgumentExpression> arguments) { | ||
arguments.removeIf(a -> a.getArgName().equalsIgnoreCase("query")); | ||
} | ||
|
||
@Override | ||
protected void checkValidArguments(String argNormalized, T queryBuilder) { | ||
if (!getQueryBuildActions().containsKey(argNormalized)) { | ||
throw new SemanticCheckException( | ||
String.format("Parameter %s is invalid for %s function.", | ||
argNormalized, getQueryName())); | ||
} | ||
} | ||
/** | ||
* Override build function because RelevanceQuery requires 2 fields, | ||
* but NoFieldQuery must have no fields. | ||
* | ||
* @param func : Contains function name and passed in arguments. | ||
* @return : QueryBuilder object | ||
*/ | ||
|
||
@Override | ||
public QueryBuilder build(FunctionExpression func) { | ||
var arguments = func.getArguments().stream().map( | ||
a -> (NamedArgumentExpression) a).collect(Collectors.toList()); | ||
if (arguments.size() < 1) { | ||
throw new SyntaxCheckException(String.format( | ||
"%s requires at least one parameter", func.getFunctionName())); | ||
} | ||
|
||
return loadArguments(arguments); | ||
} | ||
|
||
|
||
@Override | ||
public T createQueryBuilder(List<NamedArgumentExpression> arguments) { | ||
// Extract 'query' | ||
var query = arguments.stream().filter(a -> a.getArgName().equalsIgnoreCase("query")).findFirst() | ||
.orElseThrow(() -> new SemanticCheckException("'query' parameter is missing")); | ||
|
||
return createBuilder(query.getValue().valueOf(null).stringValue()); | ||
} | ||
|
||
protected abstract T createBuilder(String query); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.sql.opensearch.storage.script.filter.lucene.relevance; | ||
|
||
import org.opensearch.index.query.QueryBuilders; | ||
import org.opensearch.index.query.QueryStringQueryBuilder; | ||
|
||
/** | ||
* Class for Lucene query that builds the query_string query. | ||
*/ | ||
public class QueryQuery extends NoFieldQuery<QueryStringQueryBuilder> { | ||
|
||
final String queryQueryName = "query"; | ||
|
||
/** | ||
* Default constructor for QueryQuery configures how RelevanceQuery.build() handles | ||
* named arguments by calling the constructor of QueryStringQuery. | ||
*/ | ||
public QueryQuery() { | ||
GabeFernandez310 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
super(FunctionParameterRepository.QueryStringQueryBuildActions); | ||
} | ||
|
||
/** | ||
* Builds QueryBuilder with query value and other default parameter values set. | ||
* | ||
* @param query : Query value for query_string query | ||
* @return : Builder for query query | ||
*/ | ||
protected QueryStringQueryBuilder createBuilder(String query) { | ||
return QueryBuilders.queryStringQuery(query); | ||
} | ||
|
||
@Override | ||
public String getQueryName() { | ||
return queryQueryName; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this wasn't working?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were some issues with escaped characters causing it to fail.