@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 testPutMappingsWithBlocks() throws Exception {
    createIndex("test");
    ensureGreen();

    for (String block : Arrays.asList(SETTING_BLOCKS_READ, SETTING_BLOCKS_WRITE)) {
      try {
        enableIndexBlock("test", block);
        assertAcked(
            client()
                .admin()
                .indices()
                .preparePutMapping("test")
                .setType("doc")
                .setSource("{\"properties\":{\"date\":{\"type\":\"integer\"}}}"));
      } finally {
        disableIndexBlock("test", block);
      }
    }

    for (String block : Arrays.asList(SETTING_READ_ONLY, SETTING_BLOCKS_METADATA)) {
      try {
        enableIndexBlock("test", block);
        assertBlocked(
            client()
                .admin()
                .indices()
                .preparePutMapping("test")
                .setType("doc")
                .setSource("{\"properties\":{\"date\":{\"type\":\"integer\"}}}"));
      } finally {
        disableIndexBlock("test", block);
      }
    }
  }
  @Test
  public void testMultipleAliasesPrecedence() throws Exception {
    client()
        .admin()
        .indices()
        .preparePutTemplate("template1")
        .setTemplate("*")
        .setOrder(0)
        .addAlias(new Alias("alias1"))
        .addAlias(new Alias("{index}-alias"))
        .addAlias(new Alias("alias3").filter(FilterBuilders.missingFilter("test")))
        .addAlias(new Alias("alias4"))
        .get();

    client()
        .admin()
        .indices()
        .preparePutTemplate("template2")
        .setTemplate("te*")
        .setOrder(1)
        .addAlias(new Alias("alias1").routing("test"))
        .addAlias(new Alias("alias3"))
        .get();

    assertAcked(
        prepareCreate("test").addAlias(new Alias("test-alias").searchRouting("test-routing")));

    ensureGreen();

    GetAliasesResponse getAliasesResponse =
        client().admin().indices().prepareGetAliases().addIndices("test").get();
    assertThat(getAliasesResponse.getAliases().get("test").size(), equalTo(4));

    for (AliasMetaData aliasMetaData : getAliasesResponse.getAliases().get("test")) {
      assertThat(
          aliasMetaData.alias(),
          anyOf(equalTo("alias1"), equalTo("test-alias"), equalTo("alias3"), equalTo("alias4")));
      if ("alias1".equals(aliasMetaData.alias())) {
        assertThat(aliasMetaData.indexRouting(), equalTo("test"));
        assertThat(aliasMetaData.searchRouting(), equalTo("test"));
      } else if ("alias3".equals(aliasMetaData.alias())) {
        assertThat(aliasMetaData.filter(), nullValue());
      } else if ("test-alias".equals(aliasMetaData.alias())) {
        assertThat(aliasMetaData.indexRouting(), nullValue());
        assertThat(aliasMetaData.searchRouting(), equalTo("test-routing"));
      }
    }
  }
  @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 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 testNullShape() throws Exception {
    String mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("type1")
            .startObject("properties")
            .startObject("location")
            .field("type", "geo_shape")
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();
    assertAcked(prepareCreate("test").addMapping("type1", mapping));
    ensureGreen();

    indexRandom(
        false,
        client().prepareIndex("test", "type1", "aNullshape").setSource("{\"location\": null}"));
    GetResponse result = client().prepareGet("test", "type1", "aNullshape").execute().actionGet();
    assertThat(result.getField("location"), nullValue());
  }
  @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 that orientation parameter correctly persists across cluster restart
   *
   * @throws IOException
   */
  public void testOrientationPersistence() throws Exception {
    String idxName = "orientation";
    String mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("shape")
            .startObject("properties")
            .startObject("location")
            .field("type", "geo_shape")
            .field("orientation", "left")
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();

    // create index
    assertAcked(prepareCreate(idxName).addMapping("shape", mapping));

    mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("shape")
            .startObject("properties")
            .startObject("location")
            .field("type", "geo_shape")
            .field("orientation", "right")
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();

    assertAcked(prepareCreate(idxName + "2").addMapping("shape", mapping));
    ensureGreen(idxName, idxName + "2");

    internalCluster().fullRestart();
    ensureGreen(idxName, idxName + "2");

    // left orientation test
    IndicesService indicesService =
        internalCluster().getInstance(IndicesService.class, findNodeName(idxName));
    IndexService indexService = indicesService.indexService(idxName);
    FieldMapper fieldMapper = indexService.mapperService().smartNameFieldMapper("location");
    assertThat(fieldMapper, instanceOf(GeoShapeFieldMapper.class));

    GeoShapeFieldMapper gsfm = (GeoShapeFieldMapper) fieldMapper;
    ShapeBuilder.Orientation orientation = gsfm.orientation();
    assertThat(orientation, equalTo(ShapeBuilder.Orientation.CLOCKWISE));
    assertThat(orientation, equalTo(ShapeBuilder.Orientation.LEFT));
    assertThat(orientation, equalTo(ShapeBuilder.Orientation.CW));

    // right orientation test
    indicesService =
        internalCluster().getInstance(IndicesService.class, findNodeName(idxName + "2"));
    indexService = indicesService.indexService(idxName + "2");
    fieldMapper = indexService.mapperService().smartNameFieldMapper("location");
    assertThat(fieldMapper, instanceOf(GeoShapeFieldMapper.class));

    gsfm = (GeoShapeFieldMapper) fieldMapper;
    orientation = gsfm.orientation();
    assertThat(orientation, equalTo(ShapeBuilder.Orientation.COUNTER_CLOCKWISE));
    assertThat(orientation, equalTo(ShapeBuilder.Orientation.RIGHT));
    assertThat(orientation, equalTo(ShapeBuilder.Orientation.CCW));
  }
  @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 // Issue 2944
  public void testThatShapeIsReturnedEvenWhenExclusionsAreSet() throws Exception {
    String mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("type1")
            .startObject("properties")
            .startObject("location")
            .field("type", "geo_shape")
            .endObject()
            .endObject()
            .startObject("_source")
            .startArray("excludes")
            .value("nonExistingField")
            .endArray()
            .endObject()
            .endObject()
            .endObject()
            .string();
    assertAcked(prepareCreate("test").addMapping("type1", mapping));
    ensureGreen();

    indexRandom(
        true,
        client()
            .prepareIndex("test", "type1", "1")
            .setSource(
                jsonBuilder()
                    .startObject()
                    .field("name", "Document 1")
                    .startObject("location")
                    .field("type", "envelope")
                    .startArray("coordinates")
                    .startArray()
                    .value(-45.0)
                    .value(45)
                    .endArray()
                    .startArray()
                    .value(45)
                    .value(-45)
                    .endArray()
                    .endArray()
                    .endObject()
                    .endObject()));

    SearchResponse searchResponse =
        client()
            .prepareSearch("test")
            .setQuery(QueryBuilders.matchAllQuery())
            .execute()
            .actionGet();
    assertThat(searchResponse.getHits().totalHits(), equalTo(1L));

    Map<String, Object> indexedMap = searchResponse.getHits().getAt(0).sourceAsMap();
    assertThat(indexedMap.get("location"), instanceOf(Map.class));
    Map<String, Object> locationMap = (Map<String, Object>) indexedMap.get("location");
    assertThat(locationMap.get("coordinates"), instanceOf(List.class));
    List<List<Number>> coordinates = (List<List<Number>>) locationMap.get("coordinates");
    assertThat(coordinates.size(), equalTo(2));
    assertThat(coordinates.get(0).size(), equalTo(2));
    assertThat(coordinates.get(0).get(0).doubleValue(), equalTo(-45.0));
    assertThat(coordinates.get(0).get(1).doubleValue(), equalTo(45.0));
    assertThat(coordinates.get(1).size(), equalTo(2));
    assertThat(coordinates.get(1).get(0).doubleValue(), equalTo(45.0));
    assertThat(coordinates.get(1).get(1).doubleValue(), equalTo(-45.0));
    assertThat(locationMap.size(), equalTo(2));
  }
  @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 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 testIndexPointsFilterRectangle() throws Exception {
    String mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("type1")
            .startObject("properties")
            .startObject("location")
            .field("type", "geo_shape")
            .field("tree", "quadtree")
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();
    assertAcked(prepareCreate("test").addMapping("type1", mapping));
    ensureGreen();

    indexRandom(
        true,
        client()
            .prepareIndex("test", "type1", "1")
            .setSource(
                jsonBuilder()
                    .startObject()
                    .field("name", "Document 1")
                    .startObject("location")
                    .field("type", "point")
                    .startArray("coordinates")
                    .value(-30)
                    .value(-30)
                    .endArray()
                    .endObject()
                    .endObject()),
        client()
            .prepareIndex("test", "type1", "2")
            .setSource(
                jsonBuilder()
                    .startObject()
                    .field("name", "Document 2")
                    .startObject("location")
                    .field("type", "point")
                    .startArray("coordinates")
                    .value(-45)
                    .value(-50)
                    .endArray()
                    .endObject()
                    .endObject()));

    ShapeBuilder shape = ShapeBuilder.newEnvelope().topLeft(-45, 45).bottomRight(45, -45);

    SearchResponse searchResponse =
        client()
            .prepareSearch()
            .setQuery(filteredQuery(matchAllQuery(), geoIntersectionFilter("location", shape)))
            .execute()
            .actionGet();

    assertSearchResponse(searchResponse);
    assertThat(searchResponse.getHits().getTotalHits(), equalTo(1l));
    assertThat(searchResponse.getHits().hits().length, equalTo(1));
    assertThat(searchResponse.getHits().getAt(0).id(), equalTo("1"));

    searchResponse =
        client().prepareSearch().setQuery(geoShapeQuery("location", shape)).execute().actionGet();

    assertSearchResponse(searchResponse);
    assertThat(searchResponse.getHits().getTotalHits(), equalTo(1l));
    assertThat(searchResponse.getHits().hits().length, equalTo(1));
    assertThat(searchResponse.getHits().getAt(0).id(), equalTo("1"));
  }
  @Test
  public void testEdgeCases() throws Exception {

    String mapping =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("type1")
            .startObject("properties")
            .startObject("location")
            .field("type", "geo_shape")
            .field("tree", "quadtree")
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();
    assertAcked(prepareCreate("test").addMapping("type1", mapping));
    ensureGreen();

    indexRandom(
        true,
        client()
            .prepareIndex("test", "type1", "blakely")
            .setSource(
                jsonBuilder()
                    .startObject()
                    .field("name", "Blakely Island")
                    .startObject("location")
                    .field("type", "polygon")
                    .startArray("coordinates")
                    .startArray()
                    .startArray()
                    .value(-122.83)
                    .value(48.57)
                    .endArray()
                    .startArray()
                    .value(-122.77)
                    .value(48.56)
                    .endArray()
                    .startArray()
                    .value(-122.79)
                    .value(48.53)
                    .endArray()
                    .startArray()
                    .value(-122.83)
                    .value(48.57)
                    .endArray() // close the polygon
                    .endArray()
                    .endArray()
                    .endObject()
                    .endObject()));

    ShapeBuilder query =
        ShapeBuilder.newEnvelope().topLeft(-122.88, 48.62).bottomRight(-122.82, 48.54);

    // This search would fail if both geoshape indexing and geoshape filtering
    // used the bottom-level optimization in SpatialPrefixTree#recursiveGetNodes.
    SearchResponse searchResponse =
        client()
            .prepareSearch()
            .setQuery(filteredQuery(matchAllQuery(), geoIntersectionFilter("location", query)))
            .execute()
            .actionGet();

    assertSearchResponse(searchResponse);
    assertThat(searchResponse.getHits().getTotalHits(), equalTo(1l));
    assertThat(searchResponse.getHits().hits().length, equalTo(1));
    assertThat(searchResponse.getHits().getAt(0).id(), equalTo("blakely"));
  }