/*
* Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. Crate licenses
* this file to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial agreement.
*/
package io.crate.lucene.match;
import com.google.common.collect.ImmutableMap;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.search.MatchQuery;
import org.elasticsearch.index.search.MultiMatchQuery;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
public final class MatchQueries {
private static final Map<BytesRef, MultiMatchQueryBuilder.Type> SUPPORTED_TYPES =
ImmutableMap.<BytesRef, MultiMatchQueryBuilder.Type>builder()
.put(new BytesRef("best_fields"), MultiMatchQueryBuilder.Type.BEST_FIELDS)
.put(new BytesRef("most_fields"), MultiMatchQueryBuilder.Type.MOST_FIELDS)
.put(new BytesRef("cross_fields"), MultiMatchQueryBuilder.Type.CROSS_FIELDS)
.put(new BytesRef("phrase"), MultiMatchQueryBuilder.Type.PHRASE)
.put(new BytesRef("phrase_prefix"), MultiMatchQueryBuilder.Type.PHRASE_PREFIX)
.build();
public static Query singleMatch(QueryShardContext queryShardContext,
String fieldName,
BytesRef queryString,
@Nullable BytesRef matchType,
@Nullable Map<String, Object> options) throws IOException {
MultiMatchQueryBuilder.Type type = getType(matchType);
ParsedOptions parsedOptions = OptionParser.parse(type, options);
MatchQuery.Type matchQueryType = type.matchQueryType();
MatchQuery matchQuery = new MatchQuery(queryShardContext);
matchQuery.setAnalyzer(parsedOptions.analyzer());
matchQuery.setCommonTermsCutoff(parsedOptions.commonTermsCutoff());
matchQuery.setFuzziness(parsedOptions.fuzziness());
matchQuery.setFuzzyPrefixLength(parsedOptions.prefixLength());
matchQuery.setFuzzyRewriteMethod(parsedOptions.rewriteMethod());
matchQuery.setMaxExpansions(parsedOptions.maxExpansions());
matchQuery.setPhraseSlop(parsedOptions.phraseSlop());
matchQuery.setTranspositions(parsedOptions.transpositions());
matchQuery.setZeroTermsQuery(parsedOptions.zeroTermsQuery());
return matchQuery.parse(matchQueryType, fieldName, queryString.utf8ToString());
}
public static Query multiMatch(QueryShardContext queryShardContext,
@Nullable BytesRef matchType,
Map<String, Float> fieldNames,
String queryString,
Map<String, Object> options) throws IOException {
MultiMatchQueryBuilder.Type type = MatchQueries.getType(matchType);
ParsedOptions parsedOptions = OptionParser.parse(type, options);
MultiMatchQuery multiMatchQuery = new MultiMatchQuery(queryShardContext);
Float tieBreaker = parsedOptions.tieBreaker();
if (tieBreaker != null) {
multiMatchQuery.setTieBreaker(tieBreaker);
}
multiMatchQuery.setAnalyzer(parsedOptions.analyzer());
multiMatchQuery.setCommonTermsCutoff(parsedOptions.commonTermsCutoff());
multiMatchQuery.setFuzziness(parsedOptions.fuzziness());
multiMatchQuery.setFuzzyPrefixLength(parsedOptions.prefixLength());
multiMatchQuery.setFuzzyRewriteMethod(parsedOptions.rewriteMethod());
multiMatchQuery.setMaxExpansions(parsedOptions.maxExpansions());
multiMatchQuery.setPhraseSlop(parsedOptions.phraseSlop());
multiMatchQuery.setTranspositions(parsedOptions.transpositions());
multiMatchQuery.setZeroTermsQuery(parsedOptions.zeroTermsQuery());
return multiMatchQuery.parse(type, fieldNames, queryString, parsedOptions.minimumShouldMatch());
}
private static MultiMatchQueryBuilder.Type getType(@Nullable BytesRef matchType) {
if (matchType == null) {
return MultiMatchQueryBuilder.Type.BEST_FIELDS;
}
MultiMatchQueryBuilder.Type type = SUPPORTED_TYPES.get(matchType);
if (type == null) {
throw illegalMatchType(BytesRefs.toString(matchType));
}
return type;
}
private static IllegalArgumentException illegalMatchType(String matchType) {
String matchTypes = SUPPORTED_TYPES.keySet()
.stream()
.map(BytesRefs::toString)
.collect(Collectors.joining(", "));
throw new IllegalArgumentException(String.format(
Locale.ENGLISH,
"Unknown matchType \"%s\". Possible matchTypes are: %s",
matchType,
matchTypes));
}
}