mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-01 00:19:11 +00:00
Query: add option for analyze wildcard/prefix also to simple_query_string query
The query_string query has an option for analyzing wildcard/prefix (#787) by a best effort approach. This adds `analyze_wildcard` option also to simple_query_string. The default is set to `false` so the existing behavior of simple_query_string is unchanged.
This commit is contained in:
parent
85fba3636a
commit
8aa64c6b76
@ -19,9 +19,14 @@
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@ -109,7 +114,7 @@ public class SimpleQueryParser extends org.apache.lucene.queryparser.simple.Simp
|
||||
|
||||
/**
|
||||
* Dispatches to Lucene's SimpleQueryParser's newPrefixQuery, optionally
|
||||
* lowercasing the term first
|
||||
* lowercasing the term first or trying to analyze terms
|
||||
*/
|
||||
@Override
|
||||
public Query newPrefixQuery(String text) {
|
||||
@ -119,9 +124,15 @@ public class SimpleQueryParser extends org.apache.lucene.queryparser.simple.Simp
|
||||
BooleanQuery bq = new BooleanQuery(true);
|
||||
for (Map.Entry<String,Float> entry : weights.entrySet()) {
|
||||
try {
|
||||
PrefixQuery prefix = new PrefixQuery(new Term(entry.getKey(), text));
|
||||
prefix.setBoost(entry.getValue());
|
||||
bq.add(prefix, BooleanClause.Occur.SHOULD);
|
||||
if (settings.analyzeWildcard()) {
|
||||
Query analyzedQuery = newPossiblyAnalyzedQuery(entry.getKey(), text);
|
||||
analyzedQuery.setBoost(entry.getValue());
|
||||
bq.add(analyzedQuery, BooleanClause.Occur.SHOULD);
|
||||
} else {
|
||||
PrefixQuery prefix = new PrefixQuery(new Term(entry.getKey(), text));
|
||||
prefix.setBoost(entry.getValue());
|
||||
bq.add(prefix, BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
return rethrowUnlessLenient(e);
|
||||
}
|
||||
@ -129,6 +140,43 @@ public class SimpleQueryParser extends org.apache.lucene.queryparser.simple.Simp
|
||||
return super.simplify(bq);
|
||||
}
|
||||
|
||||
private Query newPossiblyAnalyzedQuery(String field, String termStr) {
|
||||
TokenStream source;
|
||||
try {
|
||||
source = getAnalyzer().tokenStream(field, termStr);
|
||||
source.reset();
|
||||
} catch (IOException e) {
|
||||
return new PrefixQuery(new Term(field, termStr));
|
||||
}
|
||||
List<String> tlist = new ArrayList<>();
|
||||
CharTermAttribute termAtt = source.addAttribute(CharTermAttribute.class);
|
||||
while (true) {
|
||||
try {
|
||||
if (!source.incrementToken()) {
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
break;
|
||||
}
|
||||
tlist.add(termAtt.toString());
|
||||
}
|
||||
try {
|
||||
source.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
if (tlist.size() == 1) {
|
||||
return new PrefixQuery(new Term(field, tlist.get(0)));
|
||||
} else {
|
||||
// build a boolean query with prefix on each one...
|
||||
BooleanQuery bq = new BooleanQuery();
|
||||
for (String token : tlist) {
|
||||
bq.add(new BooleanClause(new PrefixQuery(new Term(field, token)), BooleanClause.Occur.SHOULD));
|
||||
}
|
||||
return bq;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class encapsulating the settings for the SimpleQueryString query, with
|
||||
* their default values
|
||||
@ -137,6 +185,7 @@ public class SimpleQueryParser extends org.apache.lucene.queryparser.simple.Simp
|
||||
private Locale locale = Locale.ROOT;
|
||||
private boolean lowercaseExpandedTerms = true;
|
||||
private boolean lenient = false;
|
||||
private boolean analyzeWildcard = false;
|
||||
|
||||
public Settings() {
|
||||
|
||||
@ -165,5 +214,13 @@ public class SimpleQueryParser extends org.apache.lucene.queryparser.simple.Simp
|
||||
public boolean lenient() {
|
||||
return this.lenient;
|
||||
}
|
||||
|
||||
public void analyzeWildcard(boolean analyzeWildcard) {
|
||||
this.analyzeWildcard = analyzeWildcard;
|
||||
}
|
||||
|
||||
public boolean analyzeWildcard() {
|
||||
return analyzeWildcard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
|
||||
private int flags = -1;
|
||||
private Boolean lowercaseExpandedTerms;
|
||||
private Boolean lenient;
|
||||
private Boolean analyzeWildcard;
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
@ -128,6 +129,11 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleQueryStringBuilder analyzeWildcard(boolean analyzeWildcard) {
|
||||
this.analyzeWildcard = analyzeWildcard;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(SimpleQueryStringParser.NAME);
|
||||
@ -168,6 +174,10 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
|
||||
builder.field("lenient", lenient);
|
||||
}
|
||||
|
||||
if (analyzeWildcard != null) {
|
||||
builder.field("analyze_wildcard", analyzeWildcard);
|
||||
}
|
||||
|
||||
if (locale != null) {
|
||||
builder.field("locale", locale.toString());
|
||||
}
|
||||
|
@ -178,6 +178,8 @@ public class SimpleQueryStringParser implements QueryParser {
|
||||
sqsSettings.lowercaseExpandedTerms(parser.booleanValue());
|
||||
} else if ("lenient".equals(currentFieldName)) {
|
||||
sqsSettings.lenient(parser.booleanValue());
|
||||
} else if ("analyze_wildcard".equals(currentFieldName)) {
|
||||
sqsSettings.analyzeWildcard(parser.booleanValue());
|
||||
} else if ("_name".equals(currentFieldName)) {
|
||||
queryName = parser.text();
|
||||
} else {
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
package org.elasticsearch.search.query;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.SimpleQueryStringBuilder;
|
||||
import org.elasticsearch.index.query.SimpleQueryStringFlag;
|
||||
@ -266,4 +268,30 @@ public class SimpleQueryStringTests extends ElasticsearchIntegrationTest {
|
||||
assertHitCount(resp, 1);
|
||||
assertSearchHits(resp, "1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleQueryStringAnalyzeWildcard() throws ExecutionException, InterruptedException, IOException {
|
||||
String mapping = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
.startObject("properties")
|
||||
.startObject("location")
|
||||
.field("type", "string")
|
||||
.field("analyzer", "german")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject().string();
|
||||
|
||||
CreateIndexRequestBuilder mappingRequest = client().admin().indices().prepareCreate("test1").addMapping("type1", mapping);
|
||||
mappingRequest.execute().actionGet();
|
||||
indexRandom(true, client().prepareIndex("test1", "type1", "1").setSource("location", "Köln"));
|
||||
refresh();
|
||||
|
||||
SearchResponse searchResponse = client().prepareSearch().setQuery(simpleQueryString("Köln*").analyzeWildcard(true).field("location")).get();
|
||||
assertNoFailures(searchResponse);
|
||||
assertHitCount(searchResponse, 1l);
|
||||
assertSearchHits(searchResponse, "1");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user