private void testRightOpenRange(int precisionStep) throws Exception {
    String field = "field" + precisionStep;
    int count = 3000;
    long lower = (count - 1) * distance + (distance / 3) + startOffset;
    NumericRangeQuery<Long> q =
        NumericRangeQuery.newLongRange(field, precisionStep, lower, null, true, true);
    TopDocs topDocs = searcher.search(q, null, noDocs, Sort.INDEXORDER);
    if (VERBOSE)
      System.out.println(
          "Found "
              + q.getTotalNumberOfTerms()
              + " distinct terms in right open range for field '"
              + field
              + "'.");
    ScoreDoc[] sd = topDocs.scoreDocs;
    assertNotNull(sd);
    assertEquals("Score doc count", noDocs - count, sd.length);
    Document doc = searcher.doc(sd[0].doc);
    assertEquals("First doc", count * distance + startOffset, Long.parseLong(doc.get(field)));
    doc = searcher.doc(sd[sd.length - 1].doc);
    assertEquals("Last doc", (noDocs - 1) * distance + startOffset, Long.parseLong(doc.get(field)));

    q = NumericRangeQuery.newLongRange(field, precisionStep, lower, null, true, false);
    topDocs = searcher.search(q, null, noDocs, Sort.INDEXORDER);
    sd = topDocs.scoreDocs;
    assertNotNull(sd);
    assertEquals("Score doc count", noDocs - count, sd.length);
    doc = searcher.doc(sd[0].doc);
    assertEquals("First doc", count * distance + startOffset, Long.parseLong(doc.get(field)));
    doc = searcher.doc(sd[sd.length - 1].doc);
    assertEquals("Last doc", (noDocs - 1) * distance + startOffset, Long.parseLong(doc.get(field)));
  }
  @Test
  public void testInfiniteValues() throws Exception {
    Directory dir = newDirectory();
    IndexWriter writer =
        new IndexWriter(
            dir,
            newIndexWriterConfig(
                TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT)));
    Document doc = new Document();
    doc.add(new NumericField("double").setDoubleValue(Double.NEGATIVE_INFINITY));
    doc.add(new NumericField("long").setLongValue(Long.MIN_VALUE));
    writer.addDocument(doc);

    doc = new Document();
    doc.add(new NumericField("double").setDoubleValue(Double.POSITIVE_INFINITY));
    doc.add(new NumericField("long").setLongValue(Long.MAX_VALUE));
    writer.addDocument(doc);

    doc = new Document();
    doc.add(new NumericField("double").setDoubleValue(0.0));
    doc.add(new NumericField("long").setLongValue(0L));
    writer.addDocument(doc);
    writer.close();

    IndexSearcher s = new IndexSearcher(dir);

    Query q = NumericRangeQuery.newLongRange("long", null, null, true, true);
    TopDocs topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = NumericRangeQuery.newLongRange("long", null, null, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = NumericRangeQuery.newLongRange("long", Long.MIN_VALUE, Long.MAX_VALUE, true, true);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = NumericRangeQuery.newLongRange("long", Long.MIN_VALUE, Long.MAX_VALUE, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 1, topDocs.scoreDocs.length);

    q = NumericRangeQuery.newDoubleRange("double", null, null, true, true);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = NumericRangeQuery.newDoubleRange("double", null, null, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    s.close();
    dir.close();
  }
예제 #3
0
 private void testSorting(int precisionStep) throws Exception {
   final Random rnd = newRandom();
   String field = "field" + precisionStep;
   // 10 random tests, the index order is ascending,
   // so using a reverse sort field should retun descending documents
   for (int i = 0; i < 10; i++) {
     long lower = (long) (rnd.nextDouble() * noDocs * distance) + startOffset;
     long upper = (long) (rnd.nextDouble() * noDocs * distance) + startOffset;
     if (lower > upper) {
       long a = lower;
       lower = upper;
       upper = a;
     }
     Query tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
     TopDocs topDocs =
         searcher.search(tq, null, noDocs, new Sort(new SortField(field, SortField.LONG, true)));
     if (topDocs.totalHits == 0) continue;
     ScoreDoc[] sd = topDocs.scoreDocs;
     assertNotNull(sd);
     long last = Long.parseLong(searcher.doc(sd[0].doc).get(field));
     for (int j = 1; j < sd.length; j++) {
       long act = Long.parseLong(searcher.doc(sd[j].doc).get(field));
       assertTrue("Docs should be sorted backwards", last > act);
       last = act;
     }
   }
 }
예제 #4
0
 protected <N extends Number> NumericRangeQuery<?> numericRange(
     Class<N> clazz,
     String field,
     @Nullable N min,
     @Nullable N max,
     boolean minInc,
     boolean maxInc) {
   if (clazz.equals(Integer.class)) {
     return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc);
   } else if (clazz.equals(Double.class)) {
     return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc);
   } else if (clazz.equals(Float.class)) {
     return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc);
   } else if (clazz.equals(Long.class)) {
     return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc);
   } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) {
     return NumericRangeQuery.newIntRange(
         field,
         min != null ? min.intValue() : null,
         max != null ? max.intValue() : null,
         minInc,
         maxInc);
   } else {
     throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName());
   }
 }
예제 #5
0
 /**
  * Factory that creates a <code>NumericRangeFilter</code>, that queries a <code>long</code> range
  * using the default <code>precisionStep</code> {@link NumericUtils#PRECISION_STEP_DEFAULT} (4).
  * You can have half-open ranges (which are in fact &lt;/&le; or &gt;/&ge; queries) by setting the
  * min or max value to <code>null</code>. By setting inclusive to false, it will match all
  * documents excluding the bounds, with inclusive on, the boundaries are hits, too.
  */
 public static NumericRangeFilter<Long> newLongRange(
     final String field,
     Long min,
     Long max,
     final boolean minInclusive,
     final boolean maxInclusive) {
   return new NumericRangeFilter<Long>(
       NumericRangeQuery.newLongRange(field, min, max, minInclusive, maxInclusive));
 }
예제 #6
0
 public void testOneMatchQuery() throws Exception {
   NumericRangeQuery<Long> q =
       NumericRangeQuery.newLongRange("ascfield8", 8, 1000L, 1000L, true, true);
   assertSame(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE, q.getRewriteMethod());
   TopDocs topDocs = searcher.search(q, noDocs);
   ScoreDoc[] sd = topDocs.scoreDocs;
   assertNotNull(sd);
   assertEquals("Score doc count", 1, sd.length);
 }
예제 #7
0
 private void testRangeSplit(int precisionStep) throws Exception {
   final Random rnd = newRandom();
   String field = "ascfield" + precisionStep;
   // 50 random tests
   for (int i = 0; i < 50; i++) {
     long lower = (long) (rnd.nextDouble() * noDocs - noDocs / 2);
     long upper = (long) (rnd.nextDouble() * noDocs - noDocs / 2);
     if (lower > upper) {
       long a = lower;
       lower = upper;
       upper = a;
     }
     // test inclusive range
     Query tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
     TopDocs tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to inclusive range length",
         upper - lower + 1,
         tTopDocs.totalHits);
     // test exclusive range
     tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, false);
     tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to exclusive range length",
         Math.max(upper - lower - 1, 0),
         tTopDocs.totalHits);
     // test left exclusive range
     tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, true);
     tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to half exclusive range length",
         upper - lower,
         tTopDocs.totalHits);
     // test right exclusive range
     tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, false);
     tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to half exclusive range length",
         upper - lower,
         tTopDocs.totalHits);
   }
 }
 /**
  * test for constant score + boolean query + filter, the other tests only use the constant score
  * mode
  */
 private void testRange(int precisionStep) throws Exception {
   String field = "field" + precisionStep;
   int count = 3000;
   long lower = (distance * 3 / 2) + startOffset,
       upper = lower + count * distance + (distance / 3);
   NumericRangeQuery<Long> q =
       NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
   NumericRangeFilter<Long> f =
       NumericRangeFilter.newLongRange(field, precisionStep, lower, upper, true, true);
   int lastTerms = 0;
   for (byte i = 0; i < 3; i++) {
     TopDocs topDocs;
     int terms;
     String type;
     q.clearTotalNumberOfTerms();
     f.clearTotalNumberOfTerms();
     switch (i) {
       case 0:
         type = " (constant score filter rewrite)";
         q.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE);
         topDocs = searcher.search(q, null, noDocs, Sort.INDEXORDER);
         terms = q.getTotalNumberOfTerms();
         break;
       case 1:
         type = " (constant score boolean rewrite)";
         q.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_QUERY_REWRITE);
         topDocs = searcher.search(q, null, noDocs, Sort.INDEXORDER);
         terms = q.getTotalNumberOfTerms();
         break;
       case 2:
         type = " (filter)";
         topDocs = searcher.search(new MatchAllDocsQuery(), f, noDocs, Sort.INDEXORDER);
         terms = f.getTotalNumberOfTerms();
         break;
       default:
         return;
     }
     if (VERBOSE)
       System.out.println(
           "Found " + terms + " distinct terms in range for field '" + field + "'" + type + ".");
     ScoreDoc[] sd = topDocs.scoreDocs;
     assertNotNull(sd);
     assertEquals("Score doc count" + type, count, sd.length);
     Document doc = searcher.doc(sd[0].doc);
     assertEquals("First doc" + type, 2 * distance + startOffset, Long.parseLong(doc.get(field)));
     doc = searcher.doc(sd[sd.length - 1].doc);
     assertEquals(
         "Last doc" + type, (1 + count) * distance + startOffset, Long.parseLong(doc.get(field)));
     if (i > 0 && searcher.getIndexReader().getSequentialSubReaders().length == 1) {
       assertEquals("Distinct term number is equal for all query types", lastTerms, terms);
     }
     lastTerms = terms;
   }
 }
예제 #9
0
 public void testEqualsAndHash() throws Exception {
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test1", 4, 10L, 20L, true, true));
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test2", 4, 10L, 20L, false, true));
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test3", 4, 10L, 20L, true, false));
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test4", 4, 10L, 20L, false, false));
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test5", 4, 10L, null, true, true));
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test6", 4, null, 20L, true, true));
   QueryUtils.checkHashEquals(NumericRangeQuery.newLongRange("test7", 4, null, null, true, true));
   QueryUtils.checkEqual(
       NumericRangeQuery.newLongRange("test8", 4, 10L, 20L, true, true),
       NumericRangeQuery.newLongRange("test8", 4, 10L, 20L, true, true));
   QueryUtils.checkUnequal(
       NumericRangeQuery.newLongRange("test9", 4, 10L, 20L, true, true),
       NumericRangeQuery.newLongRange("test9", 8, 10L, 20L, true, true));
   QueryUtils.checkUnequal(
       NumericRangeQuery.newLongRange("test10a", 4, 10L, 20L, true, true),
       NumericRangeQuery.newLongRange("test10b", 4, 10L, 20L, true, true));
   QueryUtils.checkUnequal(
       NumericRangeQuery.newLongRange("test11", 4, 10L, 20L, true, true),
       NumericRangeQuery.newLongRange("test11", 4, 20L, 10L, true, true));
   QueryUtils.checkUnequal(
       NumericRangeQuery.newLongRange("test12", 4, 10L, 20L, true, true),
       NumericRangeQuery.newLongRange("test12", 4, 10L, 20L, false, true));
   QueryUtils.checkUnequal(
       NumericRangeQuery.newLongRange("test13", 4, 10L, 20L, true, true),
       NumericRangeQuery.newFloatRange("test13", 4, 10f, 20f, true, true));
   // difference to int range is tested in TestNumericRangeQuery32
 }
예제 #10
0
 private void testRandomTrieAndClassicRangeQuery(int precisionStep) throws Exception {
   final Random rnd = newRandom();
   String field = "field" + precisionStep;
   int termCountT = 0, termCountC = 0;
   for (int i = 0; i < 50; i++) {
     long lower = (long) (rnd.nextDouble() * noDocs * distance) + startOffset;
     long upper = (long) (rnd.nextDouble() * noDocs * distance) + startOffset;
     if (lower > upper) {
       long a = lower;
       lower = upper;
       upper = a;
     }
     // test inclusive range
     NumericRangeQuery<Long> tq =
         NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
     TermRangeQuery cq =
         new TermRangeQuery(
             field,
             NumericUtils.longToPrefixCoded(lower),
             NumericUtils.longToPrefixCoded(upper),
             true,
             true);
     TopDocs tTopDocs = searcher.search(tq, 1);
     TopDocs cTopDocs = searcher.search(cq, 1);
     assertEquals(
         "Returned count for NumericRangeQuery and TermRangeQuery must be equal",
         cTopDocs.totalHits,
         tTopDocs.totalHits);
     termCountT += tq.getTotalNumberOfTerms();
     termCountC += cq.getTotalNumberOfTerms();
     // test exclusive range
     tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, false);
     cq =
         new TermRangeQuery(
             field,
             NumericUtils.longToPrefixCoded(lower),
             NumericUtils.longToPrefixCoded(upper),
             false,
             false);
     tTopDocs = searcher.search(tq, 1);
     cTopDocs = searcher.search(cq, 1);
     assertEquals(
         "Returned count for NumericRangeQuery and TermRangeQuery must be equal",
         cTopDocs.totalHits,
         tTopDocs.totalHits);
     termCountT += tq.getTotalNumberOfTerms();
     termCountC += cq.getTotalNumberOfTerms();
     // test left exclusive range
     tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, true);
     cq =
         new TermRangeQuery(
             field,
             NumericUtils.longToPrefixCoded(lower),
             NumericUtils.longToPrefixCoded(upper),
             false,
             true);
     tTopDocs = searcher.search(tq, 1);
     cTopDocs = searcher.search(cq, 1);
     assertEquals(
         "Returned count for NumericRangeQuery and TermRangeQuery must be equal",
         cTopDocs.totalHits,
         tTopDocs.totalHits);
     termCountT += tq.getTotalNumberOfTerms();
     termCountC += cq.getTotalNumberOfTerms();
     // test right exclusive range
     tq = NumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, false);
     cq =
         new TermRangeQuery(
             field,
             NumericUtils.longToPrefixCoded(lower),
             NumericUtils.longToPrefixCoded(upper),
             true,
             false);
     tTopDocs = searcher.search(tq, 1);
     cTopDocs = searcher.search(cq, 1);
     assertEquals(
         "Returned count for NumericRangeQuery and TermRangeQuery must be equal",
         cTopDocs.totalHits,
         tTopDocs.totalHits);
     termCountT += tq.getTotalNumberOfTerms();
     termCountC += cq.getTotalNumberOfTerms();
   }
   if (precisionStep == Integer.MAX_VALUE) {
     assertEquals(
         "Total number of terms should be equal for unlimited precStep", termCountT, termCountC);
   } else {
     System.out.println("Average number of terms during random search on '" + field + "':");
     System.out.println(" Trie query: " + (((double) termCountT) / (50 * 4)));
     System.out.println(" Classical query: " + (((double) termCountC) / (50 * 4)));
   }
 }
예제 #11
0
  /**
   * 测试各种查询条件
   *
   * @throws IOException
   * @throws Exception
   */
  @Test
  public void testAdvancedQuery() throws Exception {

    Term term = new Term("content", "spring");

    // 1、最基本的查询条件
    TermQuery query1 = new TermQuery(term);

    // 2、数字范围查询条件  参数1、搜索域  参数2、范围的最小值   参数3、范围的最大值  参数4:是否包含最小值   参数5:是否包含最大值
    NumericRangeQuery<Long> query2 =
        NumericRangeQuery.newLongRange("size", 100L, 5000L, true, false);

    // 3、布尔查询——实质是多条件的组合查询

    BooleanQuery booleanQuery = new BooleanQuery();

    booleanQuery.add(query1, Occur.MUST);
    booleanQuery.add(query2, Occur.MUST_NOT);

    // 4、matchall查询
    MatchAllDocsQuery query3 = new MatchAllDocsQuery();

    /** 以上的各种查询条件其实都是lucene底层查询语法的封装 */
    /*		System.out.println(query1);
          System.out.println(query2);
    System.out.println(booleanQuery);
    System.out.println(query3);*/
    /**
     * content:spring size:[100 TO 5000} +content:spring -size:[100 TO 5000} :*
     *
     * <p>如果我们要直接使用查询语法来搜索,就需要用到queryparser来对语法进行解析得到各种查询条件query
     */

    // --------------------------------------------------------------------------

    // 使用查询解析器来解析语法生成查询条件
    // lucene支持的常用查询与法
    /** content:spring size:[100 TO 5000} +content:spring -size:[100 TO 5000} :* */

    // 1、构造一个查询条件解析器   参数1:默认搜索域     参数2:解析查询语句时所用的分词器
    QueryParser queryParser = new QueryParser("title", new IKAnalyzer());
    // 2、传递一个用lucene查询语法表示的字符串给parser去解析
    Query queryYufa1 = queryParser.parse("content:spring.txt");
    System.out.println(queryYufa1);
    // title:spring.txt title:spring title:txt

    Query queryYufa2 = queryParser.parse("size:[2000 TO 4000}");
    System.out.println(queryYufa2);

    /** 多个域的查询解析器 */
    String[] fields = {"title", "content", "author"};
    // 参数1: 默认搜索域(多个)   参数2:用来解析查询短语的分词器
    MultiFieldQueryParser queryParser2 = new MultiFieldQueryParser(fields, new IKAnalyzer());

    // 可以给一个精确的查询语法来解析成查询条件对象query
    Query query4 = queryParser2.parse("title:spring +content:springmvc");

    // 也可以只给一个查询短语,让它自己去对默认搜索域进行解析
    Query query5 = queryParser2.parse("小屌丝");

    System.out.println("query4---- " + query4);
    System.out.println("query5---- " + query5);
    /**
     * query4---- title:spring +content:springmvc query5---- (title:小 title:屌 title:丝) (content:小
     * content:屌 content:丝) (author:小 author:屌 author:丝)
     */
    TopDocs topDocs = indexSearcher.search(queryYufa2, 10);

    int totalHits = topDocs.totalHits;
    ScoreDoc[] scoreDocs = topDocs.scoreDocs;

    System.out.println("总命中数: " + totalHits);

    for (ScoreDoc scoreDoc : scoreDocs) {

      Document doc = indexSearcher.doc(scoreDoc.doc);

      System.out.println(doc.get("title"));
      System.out.println(doc.get("content"));
      System.out.println(doc.get("path"));
      System.out.println(doc.get("size"));
    }
  }
예제 #12
0
  @Override
  public Query getRangeQuery(
      QParser parser,
      SchemaField field,
      String min,
      String max,
      boolean minInclusive,
      boolean maxInclusive) {
    int ps = precisionStep;
    Query query = null;
    switch (type) {
      case INTEGER:
        query =
            NumericRangeQuery.newIntRange(
                field.getName(),
                ps,
                min == null ? null : Integer.parseInt(min),
                max == null ? null : Integer.parseInt(max),
                minInclusive,
                maxInclusive);
        break;
      case FLOAT:
        query =
            NumericRangeQuery.newFloatRange(
                field.getName(),
                ps,
                min == null ? null : Float.parseFloat(min),
                max == null ? null : Float.parseFloat(max),
                minInclusive,
                maxInclusive);
        break;
      case LONG:
        query =
            NumericRangeQuery.newLongRange(
                field.getName(),
                ps,
                min == null ? null : Long.parseLong(min),
                max == null ? null : Long.parseLong(max),
                minInclusive,
                maxInclusive);
        break;
      case DOUBLE:
        query =
            NumericRangeQuery.newDoubleRange(
                field.getName(),
                ps,
                min == null ? null : Double.parseDouble(min),
                max == null ? null : Double.parseDouble(max),
                minInclusive,
                maxInclusive);
        break;
      case DATE:
        query =
            NumericRangeQuery.newLongRange(
                field.getName(),
                ps,
                min == null ? null : dateField.parseMath(null, min).getTime(),
                max == null ? null : dateField.parseMath(null, max).getTime(),
                minInclusive,
                maxInclusive);
        break;
      default:
        throw new SolrException(
            SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field");
    }

    return query;
  }