public void testPointValuesMemoryIndexVsNormalIndex() throws Exception {
    int size = atLeast(12);

    List<Integer> randomValues = new ArrayList<>();

    Document doc = new Document();
    for (Integer randomInteger : random().ints(size).toArray()) {
      doc.add(new IntPoint("int", randomInteger));
      randomValues.add(randomInteger);
      doc.add(new LongPoint("long", randomInteger));
      doc.add(new FloatPoint("float", randomInteger));
      doc.add(new DoublePoint("double", randomInteger));
    }

    MockAnalyzer mockAnalyzer = new MockAnalyzer(random());
    MemoryIndex memoryIndex = MemoryIndex.fromDocument(doc, mockAnalyzer);
    IndexSearcher memoryIndexSearcher = memoryIndex.createSearcher();

    Directory dir = newDirectory();
    IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(random(), mockAnalyzer));
    writer.addDocument(doc);
    writer.close();
    IndexReader controlIndexReader = DirectoryReader.open(dir);
    IndexSearcher controlIndexSearcher = new IndexSearcher(controlIndexReader);

    Supplier<Integer> valueSupplier = () -> randomValues.get(random().nextInt(randomValues.size()));
    Query[] queries =
        new Query[] {
          IntPoint.newExactQuery("int", valueSupplier.get()),
          LongPoint.newExactQuery("long", valueSupplier.get()),
          FloatPoint.newExactQuery("float", valueSupplier.get()),
          DoublePoint.newExactQuery("double", valueSupplier.get()),
          IntPoint.newSetQuery("int", valueSupplier.get(), valueSupplier.get()),
          LongPoint.newSetQuery("long", valueSupplier.get(), valueSupplier.get()),
          FloatPoint.newSetQuery("float", valueSupplier.get(), valueSupplier.get()),
          DoublePoint.newSetQuery("double", valueSupplier.get(), valueSupplier.get()),
          IntPoint.newRangeQuery("int", valueSupplier.get(), valueSupplier.get()),
          LongPoint.newRangeQuery("long", valueSupplier.get(), valueSupplier.get()),
          FloatPoint.newRangeQuery("float", valueSupplier.get(), valueSupplier.get()),
          DoublePoint.newRangeQuery("double", valueSupplier.get(), valueSupplier.get())
        };
    for (Query query : queries) {
      assertEquals(controlIndexSearcher.count(query), controlIndexSearcher.count(query));
    }

    memoryIndexSearcher.getIndexReader().close();
    controlIndexReader.close();
    dir.close();
  }
  /**
   * Returns a numeric range query based on FieldType {@link LegacyNumericRangeQuery} is used for
   * indexes created using {@code FieldType.LegacyNumericType} {@link DoublePoint#newRangeQuery} is
   * used for indexes created using {@link DoublePoint} fields
   */
  private Query rangeQuery(String fieldName, Double min, Double max) {
    if (hasPointVals) {
      if (min == null) {
        min = Double.NEGATIVE_INFINITY;
      }

      if (max == null) {
        max = Double.POSITIVE_INFINITY;
      }

      return DoublePoint.newRangeQuery(fieldName, min, max);

    } else if (legacyNumericFieldType != null) { // todo remove legacy numeric support in 7.0
      return LegacyNumericRangeQuery.newDoubleRange(
          fieldName,
          legacyNumericFieldType.numericPrecisionStep(),
          min,
          max,
          true,
          true); // inclusive
    }
    // TODO try doc-value range query?
    throw new UnsupportedOperationException("An index is required for this operation.");
  }
  /**
   * Given a latitude and longitude (in degrees) and the maximum great circle (surface of the earth)
   * distance, returns a simple Filter bounding box to "fast match" candidates.
   */
  public static Query getBoundingBoxQuery(
      double originLat, double originLng, double maxDistanceKM) {

    // Basic bounding box geo math from
    // http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates,
    // licensed under creative commons 3.0:
    // http://creativecommons.org/licenses/by/3.0

    // TODO: maybe switch to recursive prefix tree instead
    // (in lucene/spatial)?  It should be more efficient
    // since it's a 2D trie...

    // Degrees -> Radians:
    double originLatRadians = SloppyMath.toRadians(originLat);
    double originLngRadians = SloppyMath.toRadians(originLng);

    double angle = maxDistanceKM / EARTH_RADIUS_KM;

    double minLat = originLatRadians - angle;
    double maxLat = originLatRadians + angle;

    double minLng;
    double maxLng;
    if (minLat > SloppyMath.toRadians(-90) && maxLat < SloppyMath.toRadians(90)) {
      double delta = Math.asin(Math.sin(angle) / Math.cos(originLatRadians));
      minLng = originLngRadians - delta;
      if (minLng < SloppyMath.toRadians(-180)) {
        minLng += 2 * Math.PI;
      }
      maxLng = originLngRadians + delta;
      if (maxLng > SloppyMath.toRadians(180)) {
        maxLng -= 2 * Math.PI;
      }
    } else {
      // The query includes a pole!
      minLat = Math.max(minLat, SloppyMath.toRadians(-90));
      maxLat = Math.min(maxLat, SloppyMath.toRadians(90));
      minLng = SloppyMath.toRadians(-180);
      maxLng = SloppyMath.toRadians(180);
    }

    BooleanQuery.Builder f = new BooleanQuery.Builder();

    // Add latitude range filter:
    f.add(
        DoublePoint.newRangeQuery(
            "latitude", SloppyMath.toDegrees(minLat), SloppyMath.toDegrees(maxLat)),
        BooleanClause.Occur.FILTER);

    // Add longitude range filter:
    if (minLng > maxLng) {
      // The bounding box crosses the international date
      // line:
      BooleanQuery.Builder lonF = new BooleanQuery.Builder();
      lonF.add(
          DoublePoint.newRangeQuery(
              "longitude", SloppyMath.toDegrees(minLng), Double.POSITIVE_INFINITY),
          BooleanClause.Occur.SHOULD);
      lonF.add(
          DoublePoint.newRangeQuery(
              "longitude", Double.NEGATIVE_INFINITY, SloppyMath.toDegrees(maxLng)),
          BooleanClause.Occur.SHOULD);
      f.add(lonF.build(), BooleanClause.Occur.MUST);
    } else {
      f.add(
          DoublePoint.newRangeQuery(
              "longitude", SloppyMath.toDegrees(minLng), SloppyMath.toDegrees(maxLng)),
          BooleanClause.Occur.FILTER);
    }

    return f.build();
  }
示例#4
0
    private void _run() throws IOException {
      for (int i = 0; i < iters; i++) {
        String color;
        String sortField;

        switch (random.nextInt(4)) {
          case 0:
            // TermQuery on yellow cabs
            color = "y";
            if (sparse) {
              sortField = "yellow_pickup_longitude";
            } else {
              sortField = "pickup_longitude";
            }
            break;

          case 1:
            // TermQuery on green cabs
            color = "g";
            if (sparse) {
              sortField = "green_pickup_longitude";
            } else {
              sortField = "pickup_longitude";
            }
            break;

          case 2:
            // BooleanQuery on both cabs (all docs)
            color = "both";
            sortField = null;
            break;

          case 3:
            // Point range query
            color = "neither";
            sortField = null;
            break;

          default:
            throw new AssertionError();
        }

        Query query;
        if (color.equals("both")) {
          BooleanQuery.Builder builder = new BooleanQuery.Builder();
          builder.add(new TermQuery(new Term("cab_color", "y")), BooleanClause.Occur.SHOULD);
          builder.add(new TermQuery(new Term("cab_color", "g")), BooleanClause.Occur.SHOULD);
          query = builder.build();
        } else if (color.equals("neither")) {
          if (sparse) {
            BooleanQuery.Builder builder = new BooleanQuery.Builder();
            builder.add(
                DoublePoint.newRangeQuery("green_pickup_latitude", 40.75, 40.9),
                BooleanClause.Occur.SHOULD);
            builder.add(
                DoublePoint.newRangeQuery("yellow_pickup_latitude", 40.75, 40.9),
                BooleanClause.Occur.SHOULD);
            query = builder.build();
          } else {
            query = DoublePoint.newRangeQuery("pickup_latitude", 40.75, 40.9);
          }
        } else {
          query = new TermQuery(new Term("cab_color", color));
        }
        Sort sort;
        if (sortField != null && random.nextBoolean()) {
          sort = new Sort(new SortField(sortField, SortField.Type.DOUBLE));
        } else {
          sort = null;
        }

        long t0 = System.nanoTime();
        TopDocs hits;
        if (sort == null) {
          hits = searcher.search(query, 10);
        } else {
          hits = searcher.search(query, 10, sort);
        }
        long t1 = System.nanoTime();
        results.add(
            "T"
                + threadID
                + " "
                + query
                + " sort="
                + sort
                + ": "
                + hits.totalHits
                + " hits in "
                + ((t1 - t0) / 1000000.)
                + " msec");
        for (ScoreDoc hit : hits.scoreDocs) {
          Document doc = searcher.doc(hit.doc);
          results.add("  " + hit.doc + " " + hit.score + ": " + doc.getFields().size() + " fields");
        }

        /*
        synchronized(printLock) {
          System.out.println("T" + threadID + " " + query + " sort=" + sort + ": " + hits.totalHits + " hits in " + ((t1-t0)/1000000.) + " msec");
          for(ScoreDoc hit : hits.scoreDocs) {
            Document doc = searcher.doc(hit.doc);
            System.out.println("  " + hit.doc + " " + hit.score + ": " + doc.getFields().size() + " fields");
          }
        }
        */
      }
    }