@Ignore("https://github.com/elasticsearch/elasticsearch/issues/9904")
  @Test
  public void testShapeFilterWithRandomGeoCollection() throws Exception {
    // Create a random geometry collection.
    GeometryCollectionBuilder gcb = RandomShapeGenerator.createGeometryCollection(getRandom());

    logger.info("Created Random GeometryCollection containing " + gcb.numShapes() + " shapes");

    createIndex("randshapes");
    assertAcked(prepareCreate("test").addMapping("type", "location", "type=geo_shape"));

    XContentBuilder docSource =
        gcb.toXContent(jsonBuilder().startObject().field("location"), null).endObject();
    indexRandom(true, client().prepareIndex("test", "type", "1").setSource(docSource));

    ensureSearchable("test");

    ShapeBuilder filterShape = (gcb.getShapeAt(randomIntBetween(0, gcb.numShapes() - 1)));

    GeoShapeFilterBuilder filter =
        FilterBuilders.geoShapeFilter("location", filterShape, ShapeRelation.INTERSECTS);
    SearchResponse result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
  }
  @Test
  public void testIndexTemplateWithAliasesSource() {
    client()
        .admin()
        .indices()
        .preparePutTemplate("template_1")
        .setTemplate("te*")
        .setAliases(
            "    {\n"
                + "        \"alias1\" : {},\n"
                + "        \"alias2\" : {\n"
                + "            \"filter\" : {\n"
                + "                \"type\" : {\n"
                + "                    \"value\" : \"type2\"\n"
                + "                }\n"
                + "            }\n"
                + "         },\n"
                + "        \"alias3\" : { \"routing\" : \"1\" }"
                + "    }\n")
        .get();

    assertAcked(prepareCreate("test_index").addMapping("type1").addMapping("type2"));
    ensureGreen();

    GetAliasesResponse getAliasesResponse =
        client().admin().indices().prepareGetAliases().setIndices("test_index").get();
    assertThat(getAliasesResponse.getAliases().size(), equalTo(1));
    assertThat(getAliasesResponse.getAliases().get("test_index").size(), equalTo(3));

    client().prepareIndex("test_index", "type1", "1").setSource("field", "value1").get();
    client().prepareIndex("test_index", "type2", "2").setSource("field", "value2").get();
    refresh();

    SearchResponse searchResponse = client().prepareSearch("test_index").get();
    assertHitCount(searchResponse, 2l);

    searchResponse = client().prepareSearch("alias1").get();
    assertHitCount(searchResponse, 2l);

    searchResponse = client().prepareSearch("alias2").get();
    assertHitCount(searchResponse, 1l);
    assertThat(searchResponse.getHits().getAt(0).type(), equalTo("type2"));
  }
  @Test
  public void testStringSortMissingAscTerminates() throws Exception {
    assertAcked(
        prepareCreate("test")
            .setSettings(
                Settings.settingsBuilder()
                    .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
                    .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0))
            .addMapping("test", "no_field", "type=string", "some_field", "type=string"));
    client().prepareIndex("test", "test", "1").setSource("some_field", "test").get();
    refresh();

    SearchResponse response =
        client()
            .prepareSearch("test")
            .setTypes("test")
            .addSort(new FieldSortBuilder("no_field").order(SortOrder.ASC).missing("_last"))
            .setScroll("1m")
            .get();
    assertHitCount(response, 1);
    assertSearchHits(response, "1");

    response = client().prepareSearchScroll(response.getScrollId()).get();
    assertSearchResponse(response);
    assertHitCount(response, 1);
    assertNoSearchHits(response);

    response =
        client()
            .prepareSearch("test")
            .setTypes("test")
            .addSort(new FieldSortBuilder("no_field").order(SortOrder.ASC).missing("_first"))
            .setScroll("1m")
            .get();
    assertHitCount(response, 1);
    assertSearchHits(response, "1");

    response = client().prepareSearchScroll(response.getScrollId()).get();
    assertHitCount(response, 1);
    assertThat(response.getHits().getHits().length, equalTo(0));
  }
  @Test
  public void testParsingMultipleShapes() throws Exception {
    String mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("type1")
            .startObject("properties")
            .startObject("location1")
            .field("type", "geo_shape")
            .endObject()
            .startObject("location2")
            .field("type", "geo_shape")
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();

    assertAcked(prepareCreate("test").addMapping("type1", mapping));
    ensureYellow();

    String p1 =
        "\"location1\" : {\"type\":\"polygon\", \"coordinates\":[[[-10,-10],[10,-10],[10,10],[-10,10],[-10,-10]]]}";
    String p2 =
        "\"location2\" : {\"type\":\"polygon\", \"coordinates\":[[[-20,-20],[20,-20],[20,20],[-20,20],[-20,-20]]]}";
    String o1 = "{" + p1 + ", " + p2 + "}";

    indexRandom(true, client().prepareIndex("test", "type1", "1").setSource(o1));

    String filter =
        "{\"geo_shape\": {\"location2\": {\"indexed_shape\": {"
            + "\"id\": \"1\","
            + "\"type\": \"type1\","
            + "\"index\": \"test\","
            + "\"path\": \"location2\""
            + "}}}}";

    SearchResponse result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .execute()
            .actionGet();
    assertSearchResponse(result);
    assertHitCount(result, 1);
  }
  @Test
  public void testRescorePhrase() throws Exception {
    assertAcked(
        prepareCreate("test")
            .addMapping(
                "type1",
                jsonBuilder()
                    .startObject()
                    .startObject("type1")
                    .startObject("properties")
                    .startObject("field1")
                    .field("analyzer", "whitespace")
                    .field("type", "string")
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject())
            .setSettings(
                ImmutableSettings.settingsBuilder()
                    .put(indexSettings())
                    .put("index.number_of_shards", 2)));

    client()
        .prepareIndex("test", "type1", "1")
        .setSource("field1", "the quick brown fox")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "2")
        .setSource("field1", "the quick lazy huge brown fox jumps over the tree")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "3")
        .setSource(
            "field1",
            "quick huge brown",
            "field2",
            "the quick lazy huge brown fox jumps over the tree")
        .execute()
        .actionGet();
    refresh();
    SearchResponse searchResponse =
        client()
            .prepareSearch()
            .setQuery(
                QueryBuilders.matchQuery("field1", "the quick brown")
                    .operator(MatchQueryBuilder.Operator.OR))
            .setRescorer(
                RescoreBuilder.queryRescorer(
                    QueryBuilders.matchPhraseQuery("field1", "quick brown").slop(2).boost(4.0f)))
            .setRescoreWindow(5)
            .execute()
            .actionGet();

    assertThat(searchResponse.getHits().totalHits(), equalTo(3l));
    assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
    assertThat(searchResponse.getHits().getHits()[1].getId(), equalTo("3"));
    assertThat(searchResponse.getHits().getHits()[2].getId(), equalTo("2"));

    searchResponse =
        client()
            .prepareSearch()
            .setQuery(
                QueryBuilders.matchQuery("field1", "the quick brown")
                    .operator(MatchQueryBuilder.Operator.OR))
            .setRescorer(
                RescoreBuilder.queryRescorer(
                    QueryBuilders.matchPhraseQuery("field1", "the quick brown").slop(3)))
            .setRescoreWindow(5)
            .execute()
            .actionGet();

    assertHitCount(searchResponse, 3);
    assertFirstHit(searchResponse, hasId("1"));
    assertSecondHit(searchResponse, hasId("2"));
    assertThirdHit(searchResponse, hasId("3"));

    searchResponse =
        client()
            .prepareSearch()
            .setQuery(
                QueryBuilders.matchQuery("field1", "the quick brown")
                    .operator(MatchQueryBuilder.Operator.OR))
            .setRescorer(
                RescoreBuilder.queryRescorer(
                    (QueryBuilders.matchPhraseQuery("field1", "the quick brown"))))
            .setRescoreWindow(5)
            .execute()
            .actionGet();

    assertHitCount(searchResponse, 3);
    assertFirstHit(searchResponse, hasId("1"));
    assertSecondHit(searchResponse, hasId("2"));
    assertThirdHit(searchResponse, hasId("3"));
  }
  @Test
  public void testScoring() throws Exception {
    int numDocs = indexRandomNumbers("keyword");

    String[] scoreModes = new String[] {"max", "min", "avg", "total", "multiply", ""};
    float primaryWeight = 1.1f;
    float secondaryWeight = 1.6f;

    for (String scoreMode : scoreModes) {
      for (int i = 0; i < numDocs - 4; i++) {
        String[] intToEnglish =
            new String[] {
              English.intToEnglish(i),
              English.intToEnglish(i + 1),
              English.intToEnglish(i + 2),
              English.intToEnglish(i + 3)
            };

        QueryRescorer rescoreQuery =
            RescoreBuilder.queryRescorer(
                    QueryBuilders.boolQuery()
                        .disableCoord(true)
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[0]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("5.0f")))
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[1]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("7.0f")))
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[3]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("0.0f"))))
                .setQueryWeight(primaryWeight)
                .setRescoreQueryWeight(secondaryWeight);

        if (!"".equals(scoreMode)) {
          rescoreQuery.setScoreMode(scoreMode);
        }

        SearchResponse rescored =
            client()
                .prepareSearch()
                .setPreference("test") // ensure we hit the same shards for tie-breaking
                .setQuery(
                    QueryBuilders.boolQuery()
                        .disableCoord(true)
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[0]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("2.0f")))
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[1]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("3.0f")))
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[2]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("5.0f")))
                        .should(
                            QueryBuilders.functionScoreQuery(
                                    QueryBuilders.termQuery("field1", intToEnglish[3]))
                                .boostMode(CombineFunction.REPLACE)
                                .add(ScoreFunctionBuilders.scriptFunction("0.2f"))))
                .setFrom(0)
                .setSize(10)
                .setRescorer(rescoreQuery)
                .setRescoreWindow(50)
                .execute()
                .actionGet();

        assertHitCount(rescored, 4);

        if ("total".equals(scoreMode) || "".equals(scoreMode)) {
          assertFirstHit(rescored, hasId(String.valueOf(i + 1)));
          assertSecondHit(rescored, hasId(String.valueOf(i)));
          assertThirdHit(rescored, hasId(String.valueOf(i + 2)));
          assertThat(
              rescored.getHits().getHits()[0].getScore(),
              equalTo(3.0f * primaryWeight + 7.0f * secondaryWeight));
          assertThat(
              rescored.getHits().getHits()[1].getScore(),
              equalTo(2.0f * primaryWeight + 5.0f * secondaryWeight));
          assertThat(rescored.getHits().getHits()[2].getScore(), equalTo(5.0f * primaryWeight));
          assertThat(
              rescored.getHits().getHits()[3].getScore(),
              equalTo(0.2f * primaryWeight + 0.0f * secondaryWeight));
        } else if ("max".equals(scoreMode)) {
          assertFirstHit(rescored, hasId(String.valueOf(i + 1)));
          assertSecondHit(rescored, hasId(String.valueOf(i)));
          assertThirdHit(rescored, hasId(String.valueOf(i + 2)));
          assertThat(rescored.getHits().getHits()[0].getScore(), equalTo(7.0f * secondaryWeight));
          assertThat(rescored.getHits().getHits()[1].getScore(), equalTo(5.0f * secondaryWeight));
          assertThat(rescored.getHits().getHits()[2].getScore(), equalTo(5.0f * primaryWeight));
          assertThat(rescored.getHits().getHits()[3].getScore(), equalTo(0.2f * primaryWeight));
        } else if ("min".equals(scoreMode)) {
          assertFirstHit(rescored, hasId(String.valueOf(i + 2)));
          assertSecondHit(rescored, hasId(String.valueOf(i + 1)));
          assertThirdHit(rescored, hasId(String.valueOf(i)));
          assertThat(rescored.getHits().getHits()[0].getScore(), equalTo(5.0f * primaryWeight));
          assertThat(rescored.getHits().getHits()[1].getScore(), equalTo(3.0f * primaryWeight));
          assertThat(rescored.getHits().getHits()[2].getScore(), equalTo(2.0f * primaryWeight));
          assertThat(rescored.getHits().getHits()[3].getScore(), equalTo(0.0f * secondaryWeight));
        } else if ("avg".equals(scoreMode)) {
          assertFirstHit(rescored, hasId(String.valueOf(i + 1)));
          assertSecondHit(rescored, hasId(String.valueOf(i + 2)));
          assertThirdHit(rescored, hasId(String.valueOf(i)));
          assertThat(
              rescored.getHits().getHits()[0].getScore(),
              equalTo((3.0f * primaryWeight + 7.0f * secondaryWeight) / 2.0f));
          assertThat(rescored.getHits().getHits()[1].getScore(), equalTo(5.0f * primaryWeight));
          assertThat(
              rescored.getHits().getHits()[2].getScore(),
              equalTo((2.0f * primaryWeight + 5.0f * secondaryWeight) / 2.0f));
          assertThat(
              rescored.getHits().getHits()[3].getScore(), equalTo((0.2f * primaryWeight) / 2.0f));
        } else if ("multiply".equals(scoreMode)) {
          assertFirstHit(rescored, hasId(String.valueOf(i + 1)));
          assertSecondHit(rescored, hasId(String.valueOf(i)));
          assertThirdHit(rescored, hasId(String.valueOf(i + 2)));
          assertThat(
              rescored.getHits().getHits()[0].getScore(),
              equalTo(3.0f * primaryWeight * 7.0f * secondaryWeight));
          assertThat(
              rescored.getHits().getHits()[1].getScore(),
              equalTo(2.0f * primaryWeight * 5.0f * secondaryWeight));
          assertThat(rescored.getHits().getHits()[2].getScore(), equalTo(5.0f * primaryWeight));
          assertThat(
              rescored.getHits().getHits()[3].getScore(),
              equalTo(0.2f * primaryWeight * 0.0f * secondaryWeight));
        }
      }
    }
  }
  @Test
  public void testExplain() throws Exception {
    assertAcked(
        prepareCreate("test")
            .addMapping(
                "type1",
                jsonBuilder()
                    .startObject()
                    .startObject("type1")
                    .startObject("properties")
                    .startObject("field1")
                    .field("analyzer", "whitespace")
                    .field("type", "string")
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()));
    ensureGreen();
    client()
        .prepareIndex("test", "type1", "1")
        .setSource("field1", "the quick brown fox")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "2")
        .setSource("field1", "the quick lazy huge brown fox jumps over the tree")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "3")
        .setSource(
            "field1",
            "quick huge brown",
            "field2",
            "the quick lazy huge brown fox jumps over the tree")
        .execute()
        .actionGet();
    refresh();

    {
      SearchResponse searchResponse =
          client()
              .prepareSearch()
              .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
              .setQuery(
                  QueryBuilders.matchQuery("field1", "the quick brown")
                      .operator(MatchQueryBuilder.Operator.OR))
              .setRescorer(
                  RescoreBuilder.queryRescorer(
                          QueryBuilders.matchPhraseQuery("field1", "the quick brown")
                              .slop(2)
                              .boost(4.0f))
                      .setQueryWeight(0.5f)
                      .setRescoreQueryWeight(0.4f))
              .setRescoreWindow(5)
              .setExplain(true)
              .execute()
              .actionGet();
      assertHitCount(searchResponse, 3);
      assertFirstHit(searchResponse, hasId("1"));
      assertSecondHit(searchResponse, hasId("2"));
      assertThirdHit(searchResponse, hasId("3"));

      for (int i = 0; i < 3; i++) {
        assertThat(searchResponse.getHits().getAt(i).explanation(), notNullValue());
        assertThat(searchResponse.getHits().getAt(i).explanation().isMatch(), equalTo(true));
        assertThat(searchResponse.getHits().getAt(i).explanation().getDetails().length, equalTo(2));
        assertThat(
            searchResponse.getHits().getAt(i).explanation().getDetails()[0].isMatch(),
            equalTo(true));
        if (i == 2) {
          assertThat(
              searchResponse.getHits().getAt(i).explanation().getDetails()[1].getValue(),
              equalTo(0.5f));
        } else {
          assertThat(
              searchResponse.getHits().getAt(i).explanation().getDescription(), equalTo("sum of:"));
          assertThat(
              searchResponse
                  .getHits()
                  .getAt(i)
                  .explanation()
                  .getDetails()[0]
                  .getDetails()[1]
                  .getValue(),
              equalTo(0.5f));
          assertThat(
              searchResponse
                  .getHits()
                  .getAt(i)
                  .explanation()
                  .getDetails()[1]
                  .getDetails()[1]
                  .getValue(),
              equalTo(0.4f));
        }
      }
    }

    String[] scoreModes = new String[] {"max", "min", "avg", "total", "multiply", ""};
    String[] descriptionModes =
        new String[] {"max of:", "min of:", "avg of:", "sum of:", "product of:", "sum of:"};
    for (int innerMode = 0; innerMode < scoreModes.length; innerMode++) {
      QueryRescorer innerRescoreQuery =
          RescoreBuilder.queryRescorer(
                  QueryBuilders.matchQuery("field1", "the quick brown").boost(4.0f))
              .setQueryWeight(0.5f)
              .setRescoreQueryWeight(0.4f);

      if (!"".equals(scoreModes[innerMode])) {
        innerRescoreQuery.setScoreMode(scoreModes[innerMode]);
      }

      SearchResponse searchResponse =
          client()
              .prepareSearch()
              .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
              .setQuery(
                  QueryBuilders.matchQuery("field1", "the quick brown")
                      .operator(MatchQueryBuilder.Operator.OR))
              .setRescorer(innerRescoreQuery)
              .setRescoreWindow(5)
              .setExplain(true)
              .execute()
              .actionGet();
      assertHitCount(searchResponse, 3);
      assertFirstHit(searchResponse, hasId("1"));
      assertSecondHit(searchResponse, hasId("2"));
      assertThirdHit(searchResponse, hasId("3"));

      for (int j = 0; j < 3; j++) {
        assertThat(
            searchResponse.getHits().getAt(j).explanation().getDescription(),
            equalTo(descriptionModes[innerMode]));
      }

      for (int outerMode = 0; outerMode < scoreModes.length; outerMode++) {
        QueryRescorer outerRescoreQuery =
            RescoreBuilder.queryRescorer(
                    QueryBuilders.matchQuery("field1", "the quick brown").boost(4.0f))
                .setQueryWeight(0.5f)
                .setRescoreQueryWeight(0.4f);

        if (!"".equals(scoreModes[outerMode])) {
          outerRescoreQuery.setScoreMode(scoreModes[outerMode]);
        }

        searchResponse =
            client()
                .prepareSearch()
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(
                    QueryBuilders.matchQuery("field1", "the quick brown")
                        .operator(MatchQueryBuilder.Operator.OR))
                .addRescorer(innerRescoreQuery)
                .setRescoreWindow(5)
                .addRescorer(outerRescoreQuery)
                .setRescoreWindow(10)
                .setExplain(true)
                .get();
        assertHitCount(searchResponse, 3);
        assertFirstHit(searchResponse, hasId("1"));
        assertSecondHit(searchResponse, hasId("2"));
        assertThirdHit(searchResponse, hasId("3"));

        for (int j = 0; j < 3; j++) {
          Explanation explanation = searchResponse.getHits().getAt(j).explanation();
          assertThat(explanation.getDescription(), equalTo(descriptionModes[outerMode]));
          assertThat(
              explanation.getDetails()[0].getDetails()[0].getDescription(),
              equalTo(descriptionModes[innerMode]));
        }
      }
    }
  }
  @Test
  public void testMoreDocs() throws Exception {
    Builder builder = ImmutableSettings.builder();
    builder.put("index.analysis.analyzer.synonym.tokenizer", "whitespace");
    builder.putArray("index.analysis.analyzer.synonym.filter", "synonym", "lowercase");
    builder.put("index.analysis.filter.synonym.type", "synonym");
    builder.putArray(
        "index.analysis.filter.synonym.synonyms", "ave => ave, avenue", "street => str, street");

    XContentBuilder mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("type1")
            .startObject("properties")
            .startObject("field1")
            .field("type", "string")
            .field("index_analyzer", "whitespace")
            .field("search_analyzer", "synonym")
            .endObject()
            .endObject()
            .endObject()
            .endObject();

    assertAcked(
        client()
            .admin()
            .indices()
            .prepareCreate("test")
            .addMapping("type1", mapping)
            .setSettings(builder.put("index.number_of_shards", 1)));

    client()
        .prepareIndex("test", "type1", "1")
        .setSource("field1", "massachusetts avenue boston massachusetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "2")
        .setSource("field1", "lexington avenue boston massachusetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "3")
        .setSource("field1", "boston avenue lexington massachusetts")
        .execute()
        .actionGet();
    client().admin().indices().prepareRefresh("test").execute().actionGet();
    client()
        .prepareIndex("test", "type1", "4")
        .setSource("field1", "boston road lexington massachusetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "5")
        .setSource("field1", "lexington street lexington massachusetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "6")
        .setSource("field1", "massachusetts avenue lexington massachusetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "7")
        .setSource("field1", "bosten street san franciso california")
        .execute()
        .actionGet();
    client().admin().indices().prepareRefresh("test").execute().actionGet();
    client()
        .prepareIndex("test", "type1", "8")
        .setSource("field1", "hollywood boulevard los angeles california")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "9")
        .setSource("field1", "1st street boston massachussetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "10")
        .setSource("field1", "1st street boston massachusetts")
        .execute()
        .actionGet();
    client().admin().indices().prepareRefresh("test").execute().actionGet();
    client()
        .prepareIndex("test", "type1", "11")
        .setSource("field1", "2st street boston massachusetts")
        .execute()
        .actionGet();
    client()
        .prepareIndex("test", "type1", "12")
        .setSource("field1", "3st street boston massachusetts")
        .execute()
        .actionGet();
    client().admin().indices().prepareRefresh("test").execute().actionGet();
    SearchResponse searchResponse =
        client()
            .prepareSearch()
            .setQuery(
                QueryBuilders.matchQuery("field1", "lexington avenue massachusetts")
                    .operator(MatchQueryBuilder.Operator.OR))
            .setFrom(0)
            .setSize(5)
            .setRescorer(
                RescoreBuilder.queryRescorer(
                        QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts")
                            .slop(3))
                    .setQueryWeight(0.6f)
                    .setRescoreQueryWeight(2.0f))
            .setRescoreWindow(20)
            .execute()
            .actionGet();

    assertThat(searchResponse.getHits().hits().length, equalTo(5));
    assertHitCount(searchResponse, 9);
    assertFirstHit(searchResponse, hasId("2"));
    assertSecondHit(searchResponse, hasId("6"));
    assertThirdHit(searchResponse, hasId("3"));

    searchResponse =
        client()
            .prepareSearch()
            .setQuery(
                QueryBuilders.matchQuery("field1", "lexington avenue massachusetts")
                    .operator(MatchQueryBuilder.Operator.OR))
            .setFrom(0)
            .setSize(5)
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setRescorer(
                RescoreBuilder.queryRescorer(
                        QueryBuilders.matchPhraseQuery("field1", "lexington avenue massachusetts")
                            .slop(3))
                    .setQueryWeight(0.6f)
                    .setRescoreQueryWeight(2.0f))
            .setRescoreWindow(20)
            .execute()
            .actionGet();

    assertThat(searchResponse.getHits().hits().length, equalTo(5));
    assertHitCount(searchResponse, 9);
    assertFirstHit(searchResponse, hasId("2"));
    assertSecondHit(searchResponse, hasId("6"));
    assertThirdHit(searchResponse, hasId("3"));
  }
  public void testIndexTemplateWithAliases() throws Exception {

    client()
        .admin()
        .indices()
        .preparePutTemplate("template_with_aliases")
        .setTemplate("te*")
        .addMapping(
            "type1", "{\"type1\" : {\"properties\" : {\"value\" : {\"type\" : \"string\"}}}}")
        .addAlias(new Alias("simple_alias"))
        .addAlias(new Alias("templated_alias-{index}"))
        .addAlias(new Alias("filtered_alias").filter("{\"type\":{\"value\":\"type2\"}}"))
        .addAlias(
            new Alias("complex_filtered_alias")
                .filter(
                    FilterBuilders.termsFilter("_type", "typeX", "typeY", "typeZ")
                        .execution("bool")
                        .cache(true)))
        .get();

    assertAcked(
        prepareCreate("test_index")
            .addMapping("type1")
            .addMapping("type2")
            .addMapping("typeX")
            .addMapping("typeY")
            .addMapping("typeZ"));
    ensureGreen();

    client().prepareIndex("test_index", "type1", "1").setSource("field", "A value").get();
    client().prepareIndex("test_index", "type2", "2").setSource("field", "B value").get();
    client().prepareIndex("test_index", "typeX", "3").setSource("field", "C value").get();
    client().prepareIndex("test_index", "typeY", "4").setSource("field", "D value").get();
    client().prepareIndex("test_index", "typeZ", "5").setSource("field", "E value").get();

    GetAliasesResponse getAliasesResponse =
        client().admin().indices().prepareGetAliases().setIndices("test_index").get();
    assertThat(getAliasesResponse.getAliases().size(), equalTo(1));
    assertThat(getAliasesResponse.getAliases().get("test_index").size(), equalTo(4));

    refresh();

    SearchResponse searchResponse = client().prepareSearch("test_index").get();
    assertHitCount(searchResponse, 5l);

    searchResponse = client().prepareSearch("simple_alias").get();
    assertHitCount(searchResponse, 5l);

    searchResponse = client().prepareSearch("templated_alias-test_index").get();
    assertHitCount(searchResponse, 5l);

    searchResponse = client().prepareSearch("filtered_alias").get();
    assertHitCount(searchResponse, 1l);
    assertThat(searchResponse.getHits().getAt(0).type(), equalTo("type2"));

    // Search the complex filter alias
    searchResponse = client().prepareSearch("complex_filtered_alias").get();
    assertHitCount(searchResponse, 3l);

    Set<String> types = Sets.newHashSet();
    for (SearchHit searchHit : searchResponse.getHits().getHits()) {
      types.add(searchHit.getType());
    }
    assertThat(types.size(), equalTo(3));
    assertThat(types, containsInAnyOrder("typeX", "typeY", "typeZ"));
  }
  @Test
  public void simpleIndexTemplateTests() throws Exception {
    // clean all templates setup by the framework.
    client().admin().indices().prepareDeleteTemplate("*").get();

    // check get all templates on an empty index.
    GetIndexTemplatesResponse response = client().admin().indices().prepareGetTemplates().get();
    assertThat(response.getIndexTemplates(), empty());

    client()
        .admin()
        .indices()
        .preparePutTemplate("template_1")
        .setTemplate("te*")
        .setOrder(0)
        .addMapping(
            "type1",
            XContentFactory.jsonBuilder()
                .startObject()
                .startObject("type1")
                .startObject("properties")
                .startObject("field1")
                .field("type", "string")
                .field("store", "yes")
                .endObject()
                .startObject("field2")
                .field("type", "string")
                .field("store", "yes")
                .field("index", "not_analyzed")
                .endObject()
                .endObject()
                .endObject()
                .endObject())
        .get();

    client()
        .admin()
        .indices()
        .preparePutTemplate("template_2")
        .setTemplate("test*")
        .setOrder(1)
        .addMapping(
            "type1",
            XContentFactory.jsonBuilder()
                .startObject()
                .startObject("type1")
                .startObject("properties")
                .startObject("field2")
                .field("type", "string")
                .field("store", "no")
                .endObject()
                .endObject()
                .endObject()
                .endObject())
        .get();

    // test create param
    assertThrows(
        client()
            .admin()
            .indices()
            .preparePutTemplate("template_2")
            .setTemplate("test*")
            .setCreate(true)
            .setOrder(1)
            .addMapping(
                "type1",
                XContentFactory.jsonBuilder()
                    .startObject()
                    .startObject("type1")
                    .startObject("properties")
                    .startObject("field2")
                    .field("type", "string")
                    .field("store", "no")
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject()),
        IndexTemplateAlreadyExistsException.class);

    response = client().admin().indices().prepareGetTemplates().get();
    assertThat(response.getIndexTemplates(), hasSize(2));

    // index something into test_index, will match on both templates
    client()
        .prepareIndex("test_index", "type1", "1")
        .setSource("field1", "value1", "field2", "value 2")
        .setRefresh(true)
        .execute()
        .actionGet();

    client()
        .admin()
        .cluster()
        .prepareHealth()
        .setWaitForEvents(Priority.LANGUID)
        .setWaitForGreenStatus()
        .execute()
        .actionGet();

    SearchResponse searchResponse =
        client()
            .prepareSearch("test_index")
            .setQuery(termQuery("field1", "value1"))
            .addField("field1")
            .addField("field2")
            .execute()
            .actionGet();

    assertHitCount(searchResponse, 1);
    assertThat(
        searchResponse.getHits().getAt(0).field("field1").value().toString(), equalTo("value1"));
    assertThat(
        searchResponse.getHits().getAt(0).field("field2").value().toString(),
        equalTo("value 2")); // this will still be loaded because of the source feature

    client()
        .prepareIndex("text_index", "type1", "1")
        .setSource("field1", "value1", "field2", "value 2")
        .setRefresh(true)
        .execute()
        .actionGet();

    client()
        .admin()
        .cluster()
        .prepareHealth()
        .setWaitForEvents(Priority.LANGUID)
        .setWaitForGreenStatus()
        .execute()
        .actionGet();

    // now only match on one template (template_1)
    searchResponse =
        client()
            .prepareSearch("text_index")
            .setQuery(termQuery("field1", "value1"))
            .addField("field1")
            .addField("field2")
            .execute()
            .actionGet();
    if (searchResponse.getFailedShards() > 0) {
      logger.warn("failed search " + Arrays.toString(searchResponse.getShardFailures()));
    }
    assertHitCount(searchResponse, 1);
    assertThat(
        searchResponse.getHits().getAt(0).field("field1").value().toString(), equalTo("value1"));
    assertThat(
        searchResponse.getHits().getAt(0).field("field2").value().toString(), equalTo("value 2"));
  }
  @Test
  public void testShapeFilterWithDefinedGeoCollection() throws Exception {
    createIndex("shapes");
    assertAcked(prepareCreate("test").addMapping("type", "location", "type=geo_shape"));

    XContentBuilder docSource =
        jsonBuilder()
            .startObject()
            .startObject("location")
            .field("type", "geometrycollection")
            .startArray("geometries")
            .startObject()
            .field("type", "point")
            .startArray("coordinates")
            .value(100.0)
            .value(0.0)
            .endArray()
            .endObject()
            .startObject()
            .field("type", "linestring")
            .startArray("coordinates")
            .startArray()
            .value(101.0)
            .value(0.0)
            .endArray()
            .startArray()
            .value(102.0)
            .value(1.0)
            .endArray()
            .endArray()
            .endObject()
            .endArray()
            .endObject()
            .endObject();
    indexRandom(true, client().prepareIndex("test", "type", "1").setSource(docSource));
    ensureSearchable("test");

    GeoShapeFilterBuilder filter =
        FilterBuilders.geoShapeFilter(
            "location",
            ShapeBuilder.newGeometryCollection()
                .polygon(
                    ShapeBuilder.newPolygon()
                        .point(99.0, -1.0)
                        .point(99.0, 3.0)
                        .point(103.0, 3.0)
                        .point(103.0, -1.0)
                        .point(99.0, -1.0)),
            ShapeRelation.INTERSECTS);
    SearchResponse result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    filter =
        FilterBuilders.geoShapeFilter(
            "location",
            ShapeBuilder.newGeometryCollection()
                .polygon(
                    ShapeBuilder.newPolygon()
                        .point(199.0, -11.0)
                        .point(199.0, 13.0)
                        .point(193.0, 13.0)
                        .point(193.0, -11.0)
                        .point(199.0, -11.0)),
            ShapeRelation.INTERSECTS);
    result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 0);
    filter =
        FilterBuilders.geoShapeFilter(
            "location",
            ShapeBuilder.newGeometryCollection()
                .polygon(
                    ShapeBuilder.newPolygon()
                        .point(99.0, -1.0)
                        .point(99.0, 3.0)
                        .point(103.0, 3.0)
                        .point(103.0, -1.0)
                        .point(99.0, -1.0))
                .polygon(
                    ShapeBuilder.newPolygon()
                        .point(199.0, -11.0)
                        .point(199.0, 13.0)
                        .point(193.0, 13.0)
                        .point(193.0, -11.0)
                        .point(199.0, -11.0)),
            ShapeRelation.INTERSECTS);
    result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
  }
  @Test
  public void testShapeFetchingPath() throws Exception {
    createIndex("shapes");
    assertAcked(prepareCreate("test").addMapping("type", "location", "type=geo_shape"));

    String location =
        "\"location\" : {\"type\":\"polygon\", \"coordinates\":[[[-10,-10],[10,-10],[10,10],[-10,10],[-10,-10]]]}";
    indexRandom(
        true,
        client()
            .prepareIndex("shapes", "type", "1")
            .setSource(
                String.format(
                    Locale.ROOT,
                    "{ %s, \"1\" : { %s, \"2\" : { %s, \"3\" : { %s } }} }",
                    location,
                    location,
                    location,
                    location)),
        client()
            .prepareIndex("test", "type", "1")
            .setSource(
                jsonBuilder()
                    .startObject()
                    .startObject("location")
                    .field("type", "polygon")
                    .startArray("coordinates")
                    .startArray()
                    .startArray()
                    .value(-20)
                    .value(-20)
                    .endArray()
                    .startArray()
                    .value(20)
                    .value(-20)
                    .endArray()
                    .startArray()
                    .value(20)
                    .value(20)
                    .endArray()
                    .startArray()
                    .value(-20)
                    .value(20)
                    .endArray()
                    .startArray()
                    .value(-20)
                    .value(-20)
                    .endArray()
                    .endArray()
                    .endArray()
                    .endObject()
                    .endObject()));
    ensureSearchable("test", "shapes");

    GeoShapeFilterBuilder filter =
        FilterBuilders.geoShapeFilter("location", "1", "type", ShapeRelation.INTERSECTS)
            .indexedShapeIndex("shapes")
            .indexedShapePath("location");
    SearchResponse result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    filter =
        FilterBuilders.geoShapeFilter("location", "1", "type", ShapeRelation.INTERSECTS)
            .indexedShapeIndex("shapes")
            .indexedShapePath("1.location");
    result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    filter =
        FilterBuilders.geoShapeFilter("location", "1", "type", ShapeRelation.INTERSECTS)
            .indexedShapeIndex("shapes")
            .indexedShapePath("1.2.location");
    result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    filter =
        FilterBuilders.geoShapeFilter("location", "1", "type", ShapeRelation.INTERSECTS)
            .indexedShapeIndex("shapes")
            .indexedShapePath("1.2.3.location");
    result =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .setPostFilter(filter)
            .get();
    assertSearchResponse(result);
    assertHitCount(result, 1);

    // now test the query variant
    GeoShapeQueryBuilder query =
        QueryBuilders.geoShapeQuery("location", "1", "type")
            .indexedShapeIndex("shapes")
            .indexedShapePath("location");
    result = client().prepareSearch("test").setQuery(query).get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    query =
        QueryBuilders.geoShapeQuery("location", "1", "type")
            .indexedShapeIndex("shapes")
            .indexedShapePath("1.location");
    result = client().prepareSearch("test").setQuery(query).get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    query =
        QueryBuilders.geoShapeQuery("location", "1", "type")
            .indexedShapeIndex("shapes")
            .indexedShapePath("1.2.location");
    result = client().prepareSearch("test").setQuery(query).get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
    query =
        QueryBuilders.geoShapeQuery("location", "1", "type")
            .indexedShapeIndex("shapes")
            .indexedShapePath("1.2.3.location");
    result = client().prepareSearch("test").setQuery(query).get();
    assertSearchResponse(result);
    assertHitCount(result, 1);
  }
  @Test
  public void testNoMasterActions_writeMasterBlock() throws Exception {
    Settings settings =
        settingsBuilder()
            .put("discovery.type", "zen")
            .put("action.auto_create_index", false)
            .put("discovery.zen.minimum_master_nodes", 2)
            .put("discovery.zen.ping_timeout", "200ms")
            .put("discovery.initial_state_timeout", "500ms")
            .put(DiscoverySettings.NO_MASTER_BLOCK, "write")
            .build();

    internalCluster().startNode(settings);
    // start a second node, create an index, and then shut it down so we have no master block
    internalCluster().startNode(settings);
    prepareCreate("test1").setSettings(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).get();
    prepareCreate("test2")
        .setSettings(
            IndexMetaData.SETTING_NUMBER_OF_SHARDS, 2, IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
        .get();
    client().admin().cluster().prepareHealth("_all").setWaitForGreenStatus().get();
    client().prepareIndex("test1", "type1", "1").setSource("field", "value1").get();
    client().prepareIndex("test2", "type1", "1").setSource("field", "value1").get();
    refresh();

    ensureSearchable("test1", "test2");

    ClusterStateResponse clusterState = client().admin().cluster().prepareState().get();
    logger.info("Cluster state:\n" + clusterState.getState().prettyPrint());

    internalCluster().stopRandomDataNode();
    assertThat(
        awaitBusy(
            new Predicate<Object>() {
              public boolean apply(Object o) {
                ClusterState state =
                    client().admin().cluster().prepareState().setLocal(true).get().getState();
                return state.blocks().hasGlobalBlock(DiscoverySettings.NO_MASTER_BLOCK_ID);
              }
            }),
        equalTo(true));

    GetResponse getResponse = client().prepareGet("test1", "type1", "1").get();
    assertExists(getResponse);

    CountResponse countResponse = client().prepareCount("test1").get();
    assertHitCount(countResponse, 1l);

    SearchResponse searchResponse = client().prepareSearch("test1").get();
    assertHitCount(searchResponse, 1l);

    countResponse = client().prepareCount("test2").get();
    assertThat(countResponse.getTotalShards(), equalTo(2));
    assertThat(countResponse.getSuccessfulShards(), equalTo(1));

    TimeValue timeout = TimeValue.timeValueMillis(200);
    long now = System.currentTimeMillis();
    try {
      client()
          .prepareUpdate("test1", "type1", "1")
          .setDoc("field", "value2")
          .setTimeout(timeout)
          .get();
      fail("Expected ClusterBlockException");
    } catch (ClusterBlockException e) {
      assertThat(System.currentTimeMillis() - now, greaterThan(timeout.millis() - 50));
      assertThat(e.status(), equalTo(RestStatus.SERVICE_UNAVAILABLE));
    }

    now = System.currentTimeMillis();
    try {
      client()
          .prepareIndex("test1", "type1", "1")
          .setSource(XContentFactory.jsonBuilder().startObject().endObject())
          .setTimeout(timeout)
          .get();
      fail("Expected ClusterBlockException");
    } catch (ClusterBlockException e) {
      assertThat(System.currentTimeMillis() - now, greaterThan(timeout.millis() - 50));
      assertThat(e.status(), equalTo(RestStatus.SERVICE_UNAVAILABLE));
    }

    internalCluster().startNode(settings);
    client().admin().cluster().prepareHealth().setWaitForGreenStatus().setWaitForNodes("2").get();
  }