View Javadoc
1   /*
2    * Copyright [2017] Wikimedia Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.wikimedia.search.extra.simswitcher;
18  
19  import static org.hamcrest.CoreMatchers.instanceOf;
20  
21  import java.io.IOException;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.Set;
26  
27  import org.apache.lucene.search.Query;
28  import org.apache.lucene.search.TermQuery;
29  import org.apache.lucene.search.similarity.LegacyBM25Similarity;
30  import org.elasticsearch.common.ParsingException;
31  import org.elasticsearch.common.compress.CompressedXContent;
32  import org.elasticsearch.common.settings.Settings;
33  import org.elasticsearch.index.mapper.MapperService;
34  import org.elasticsearch.index.query.QueryBuilder;
35  import org.elasticsearch.index.query.QueryBuilders;
36  import org.elasticsearch.index.query.QueryShardContext;
37  import org.elasticsearch.index.query.WrapperQueryBuilder;
38  import org.elasticsearch.plugins.Plugin;
39  import org.elasticsearch.test.AbstractQueryTestCase;
40  import org.elasticsearch.test.TestGeoShapeFieldMapperPlugin;
41  import org.wikimedia.search.extra.ExtraCorePlugin;
42  
43  public class SimSwitcherQueryBuilderESTest extends AbstractQueryTestCase<SimSwitcherQueryBuilder> {
44  
45      @Override
46      protected Collection<Class<? extends Plugin>> getPlugins() {
47          return Arrays.asList(ExtraCorePlugin.class, TestGeoShapeFieldMapperPlugin.class);
48      }
49  
50      @Override
51      protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
52          mapperService.merge("_doc",
53                  new CompressedXContent("{\"properties\":{" +
54                          "\"test\":{\"type\":\"text\" }" +
55                          "}}"),
56                  MapperService.MergeReason.MAPPING_UPDATE);
57      }
58  
59      @Override
60      protected Set<String> getObjectsHoldingArbitraryContent() {
61          return Collections.singleton(SimSwitcherQueryBuilder.PARAMS.getPreferredName());
62      }
63  
64      @Override
65      protected boolean builderGeneratesCacheableQueries() {
66          return false;
67      }
68  
69      @Override
70      public void testUnknownField() {
71          String json = "{\"" + SimSwitcherQueryBuilder.NAME + "\": {"
72                  + "\"newField\": \"blah\"}}";
73          ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(json));
74          assertTrue(e.getMessage().contains("newField"));
75      }
76  
77      /**
78       * Create the query that is being tested.
79       */
80      @Override
81      protected SimSwitcherQueryBuilder doCreateTestQueryBuilder() {
82          SimSwitcherQueryBuilder builder = new SimSwitcherQueryBuilder();
83          builder.setSubQuery(QueryBuilders.matchQuery("test", "test"));
84          builder.setSimilarityType("BM25");
85          Settings params = Settings.builder()
86                  .put("k1", "1.5")
87                  .put("b", "0.8")
88                  .build();
89          builder.setParams(params);
90          return builder;
91      }
92  
93      /**
94       * This test ensures that queries that need to be rewritten have dedicated tests.
95       * These queries must override this method accordingly.
96       */
97      @Override
98      public void testMustRewrite() throws IOException {
99          SimSwitcherQueryBuilder builder = doCreateTestQueryBuilder();
100         QueryBuilder qb = builder.getSubQuery();
101         builder.setSubQuery(new WrapperQueryBuilder(builder.getSubQuery().toString()));
102         UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, () -> builder.toQuery(createShardContext()));
103         assertEquals("this query must be rewritten first", e.getMessage());
104         QueryBuilder rewrite = builder.rewrite(createShardContext());
105         assertEquals(qb, ((SimSwitcherQueryBuilder) rewrite).getSubQuery());
106     }
107 
108     @Override
109     protected void doAssertLuceneQuery(SimSwitcherQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
110         assertThat(query, instanceOf(SimSwitcherQuery.class));
111         SimSwitcherQuery q = (SimSwitcherQuery) query;
112         assertThat(q.getSimilarity(), instanceOf(LegacyBM25Similarity.class));
113         assertThat(q.getSubQuery(), instanceOf(TermQuery.class));
114         assertEquals(0.8F, ((LegacyBM25Similarity)q.getSimilarity()).getB(), Math.ulp(0.8F));
115         assertEquals(1.5F, ((LegacyBM25Similarity)q.getSimilarity()).getK1(), Math.ulp(1.5F));
116     }
117 }