Search in sources :

Example 1 with PointInSetQuery

use of org.apache.lucene.search.PointInSetQuery in project lucene-solr by apache.

the class HalfFloatPoint method newSetQuery.

/**
   * Create a query matching any of the specified 1D values.
   * This is the points equivalent of {@code TermsQuery}.
   * Values will be rounded to the closest half-float if they
   * cannot be represented accurately as a half-float.
   *
   * @param field field name. must not be {@code null}.
   * @param values all values to match
   */
public static Query newSetQuery(String field, float... values) {
    // Don't unexpectedly change the user's incoming values array:
    float[] sortedValues = values.clone();
    Arrays.sort(sortedValues);
    final BytesRef encoded = new BytesRef(new byte[BYTES]);
    return new PointInSetQuery(field, 1, BYTES, new PointInSetQuery.Stream() {

        int upto;

        @Override
        public BytesRef next() {
            if (upto == sortedValues.length) {
                return null;
            } else {
                encodeDimension(sortedValues[upto], encoded.bytes, 0);
                upto++;
                return encoded;
            }
        }
    }) {

        @Override
        protected String toString(byte[] value) {
            assert value.length == BYTES;
            return Float.toString(decodeDimension(value, 0));
        }
    };
}
Also used : PointInSetQuery(org.apache.lucene.search.PointInSetQuery) BytesRef(org.apache.lucene.util.BytesRef)

Example 2 with PointInSetQuery

use of org.apache.lucene.search.PointInSetQuery in project lucene-solr by apache.

the class InetAddressPoint method newSetQuery.

/**
   * Create a query matching any of the specified 1D values.  This is the points equivalent of {@code TermsQuery}.
   * 
   * @param field field name. must not be {@code null}.
   * @param values all values to match
   */
public static Query newSetQuery(String field, InetAddress... values) {
    // We must compare the encoded form (InetAddress doesn't implement Comparable, and even if it
    // did, we do our own thing with ipv4 addresses):
    // NOTE: we could instead convert-per-comparison and save this extra array, at cost of slower sort:
    byte[][] sortedValues = new byte[values.length][];
    for (int i = 0; i < values.length; i++) {
        sortedValues[i] = encode(values[i]);
    }
    Arrays.sort(sortedValues, new Comparator<byte[]>() {

        @Override
        public int compare(byte[] a, byte[] b) {
            return StringHelper.compare(BYTES, a, 0, b, 0);
        }
    });
    final BytesRef encoded = new BytesRef(new byte[BYTES]);
    return new PointInSetQuery(field, 1, BYTES, new PointInSetQuery.Stream() {

        int upto;

        @Override
        public BytesRef next() {
            if (upto == sortedValues.length) {
                return null;
            } else {
                encoded.bytes = sortedValues[upto];
                assert encoded.bytes.length == encoded.length;
                upto++;
                return encoded;
            }
        }
    }) {

        @Override
        protected String toString(byte[] value) {
            assert value.length == BYTES;
            return decode(value).getHostAddress();
        }
    };
}
Also used : PointInSetQuery(org.apache.lucene.search.PointInSetQuery) BytesRef(org.apache.lucene.util.BytesRef)

Example 3 with PointInSetQuery

use of org.apache.lucene.search.PointInSetQuery in project lucene-solr by apache.

the class BinaryPoint method newSetQuery.

/**
   * Create a query matching any of the specified 1D values.  This is the points equivalent of {@code TermsQuery}.
   * 
   * @param field field name. must not be {@code null}.
   * @param values all values to match
   */
public static Query newSetQuery(String field, byte[]... values) {
    // Make sure all byte[] have the same length
    int bytesPerDim = -1;
    for (byte[] value : values) {
        if (bytesPerDim == -1) {
            bytesPerDim = value.length;
        } else if (value.length != bytesPerDim) {
            throw new IllegalArgumentException("all byte[] must be the same length, but saw " + bytesPerDim + " and " + value.length);
        }
    }
    if (bytesPerDim == -1) {
        // There are no points, and we cannot guess the bytesPerDim here, so we return an equivalent query:
        return new MatchNoDocsQuery("empty BinaryPoint.newSetQuery");
    }
    // Don't unexpectedly change the user's incoming values array:
    byte[][] sortedValues = values.clone();
    Arrays.sort(sortedValues, new Comparator<byte[]>() {

        @Override
        public int compare(byte[] a, byte[] b) {
            return StringHelper.compare(a.length, a, 0, b, 0);
        }
    });
    final BytesRef encoded = new BytesRef(new byte[bytesPerDim]);
    return new PointInSetQuery(field, 1, bytesPerDim, new PointInSetQuery.Stream() {

        int upto;

        @Override
        public BytesRef next() {
            if (upto == sortedValues.length) {
                return null;
            } else {
                encoded.bytes = sortedValues[upto];
                upto++;
                return encoded;
            }
        }
    }) {

        @Override
        protected String toString(byte[] value) {
            return new BytesRef(value).toString();
        }
    };
}
Also used : MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) PointInSetQuery(org.apache.lucene.search.PointInSetQuery) BytesRef(org.apache.lucene.util.BytesRef)

Example 4 with PointInSetQuery

use of org.apache.lucene.search.PointInSetQuery in project lucene-solr by apache.

the class DoublePoint method newSetQuery.

/**
   * Create a query matching any of the specified 1D values.  This is the points equivalent of {@code TermsQuery}.
   * 
   * @param field field name. must not be {@code null}.
   * @param values all values to match
   */
public static Query newSetQuery(String field, double... values) {
    // Don't unexpectedly change the user's incoming values array:
    double[] sortedValues = values.clone();
    Arrays.sort(sortedValues);
    final BytesRef encoded = new BytesRef(new byte[Double.BYTES]);
    return new PointInSetQuery(field, 1, Double.BYTES, new PointInSetQuery.Stream() {

        int upto;

        @Override
        public BytesRef next() {
            if (upto == sortedValues.length) {
                return null;
            } else {
                encodeDimension(sortedValues[upto], encoded.bytes, 0);
                upto++;
                return encoded;
            }
        }
    }) {

        @Override
        protected String toString(byte[] value) {
            assert value.length == Double.BYTES;
            return Double.toString(decodeDimension(value, 0));
        }
    };
}
Also used : PointInSetQuery(org.apache.lucene.search.PointInSetQuery) BytesRef(org.apache.lucene.util.BytesRef)

Example 5 with PointInSetQuery

use of org.apache.lucene.search.PointInSetQuery in project lucene-solr by apache.

the class TestSolrQueryParser method testAutoTerms.

// automatically use TermsQuery when appropriate
@Test
public void testAutoTerms() throws Exception {
    SolrQueryRequest req = req();
    QParser qParser;
    Query q, qq;
    Map<String, String> sowFalseParamsMap = new HashMap<>();
    sowFalseParamsMap.put("sow", "false");
    Map<String, String> sowTrueParamsMap = new HashMap<>();
    sowTrueParamsMap.put("sow", "true");
    List<MapSolrParams> paramMaps = Arrays.asList(// no sow param (i.e. the default sow value) 
    new MapSolrParams(Collections.emptyMap()), new MapSolrParams(sowFalseParamsMap), new MapSolrParams(sowTrueParamsMap));
    for (MapSolrParams params : paramMaps) {
        // relevance query should not be a filter
        qParser = QParser.getParser("foo_s:(a b c)", req);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(3, ((BooleanQuery) q).clauses().size());
        // small filter query should still use BooleanQuery
        if (QueryParser.TERMS_QUERY_THRESHOLD > 3) {
            qParser = QParser.getParser("foo_s:(a b c)", req);
            qParser.setParams(params);
            // this may change in the future
            qParser.setIsFilter(true);
            q = qParser.getQuery();
            assertEquals(3, ((BooleanQuery) q).clauses().size());
        }
        // large relevancy query should use BooleanQuery
        // TODO: we may decide that string fields shouldn't have relevance in the future... change to a text field w/o a stop filter if so
        qParser = QParser.getParser("foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z)", req);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(26, ((BooleanQuery) q).clauses().size());
        // large filter query should use TermsQuery
        qParser = QParser.getParser("foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z)", req);
        // this may change in the future
        qParser.setIsFilter(true);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(26, ((TermInSetQuery) q).getTermData().size());
        // large numeric filter query should use TermsQuery (for trie fields)
        qParser = QParser.getParser("foo_ti:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
        // this may change in the future
        qParser.setIsFilter(true);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(20, ((TermInSetQuery) q).getTermData().size());
        // for point fields large filter query should use PointInSetQuery
        qParser = QParser.getParser("foo_pi:(1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11)", req);
        // this may change in the future
        qParser.setIsFilter(true);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertTrue(q instanceof PointInSetQuery);
        assertEquals(20, ((PointInSetQuery) q).getPackedPoints().size());
        // a filter() clause inside a relevancy query should be able to use a TermsQuery
        qParser = QParser.getParser("foo_s:aaa filter(foo_s:(a b c d e f g h i j k l m n o p q r s t u v w x y z))", req);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(2, ((BooleanQuery) q).clauses().size());
        qq = ((BooleanQuery) q).clauses().get(0).getQuery();
        if (qq instanceof TermQuery) {
            qq = ((BooleanQuery) q).clauses().get(1).getQuery();
        }
        if (qq instanceof FilterQuery) {
            qq = ((FilterQuery) qq).getQuery();
        }
        assertEquals(26, ((TermInSetQuery) qq).getTermData().size());
        // test mixed boolean query, including quotes (which shouldn't matter)
        qParser = QParser.getParser("foo_s:(a +aaa b -bbb c d e f bar_s:(qqq www) g h i j k l m n o p q r s t u v w x y z)", req);
        // this may change in the future
        qParser.setIsFilter(true);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(4, ((BooleanQuery) q).clauses().size());
        qq = null;
        for (BooleanClause clause : ((BooleanQuery) q).clauses()) {
            qq = clause.getQuery();
            if (qq instanceof TermInSetQuery)
                break;
        }
        assertEquals(26, ((TermInSetQuery) qq).getTermData().size());
        // test terms queries of two different fields (LUCENE-7637 changed to require all terms be in the same field)
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 17; i++) {
            char letter = (char) ('a' + i);
            sb.append("foo_s:" + letter + " bar_s:" + letter + " ");
        }
        qParser = QParser.getParser(sb.toString(), req);
        // this may change in the future
        qParser.setIsFilter(true);
        qParser.setParams(params);
        q = qParser.getQuery();
        assertEquals(2, ((BooleanQuery) q).clauses().size());
        for (BooleanClause clause : ((BooleanQuery) q).clauses()) {
            qq = clause.getQuery();
            assertEquals(17, ((TermInSetQuery) qq).getTermData().size());
        }
    }
    req.close();
}
Also used : BooleanQuery(org.apache.lucene.search.BooleanQuery) TermQuery(org.apache.lucene.search.TermQuery) Query(org.apache.lucene.search.Query) PointInSetQuery(org.apache.lucene.search.PointInSetQuery) ConstantScoreQuery(org.apache.lucene.search.ConstantScoreQuery) TermInSetQuery(org.apache.lucene.search.TermInSetQuery) TermQuery(org.apache.lucene.search.TermQuery) FilterQuery(org.apache.solr.query.FilterQuery) BooleanQuery(org.apache.lucene.search.BooleanQuery) BoostQuery(org.apache.lucene.search.BoostQuery) HashMap(java.util.HashMap) PointInSetQuery(org.apache.lucene.search.PointInSetQuery) FilterQuery(org.apache.solr.query.FilterQuery) BooleanClause(org.apache.lucene.search.BooleanClause) SolrQueryRequest(org.apache.solr.request.SolrQueryRequest) MapSolrParams(org.apache.solr.common.params.MapSolrParams) TermInSetQuery(org.apache.lucene.search.TermInSetQuery) Test(org.junit.Test)

Aggregations

PointInSetQuery (org.apache.lucene.search.PointInSetQuery)10 BytesRef (org.apache.lucene.util.BytesRef)9 HashMap (java.util.HashMap)2 MatchNoDocsQuery (org.apache.lucene.search.MatchNoDocsQuery)2 Query (org.apache.lucene.search.Query)2 IOException (java.io.IOException)1 BigInteger (java.math.BigInteger)1 Iterator (java.util.Iterator)1 Locale (java.util.Locale)1 Map (java.util.Map)1 TreeSet (java.util.TreeSet)1 BiConsumer (java.util.function.BiConsumer)1 LongFunction (java.util.function.LongFunction)1 DoublePoint (org.apache.lucene.document.DoublePoint)1 FloatPoint (org.apache.lucene.document.FloatPoint)1 IntPoint (org.apache.lucene.document.IntPoint)1 LongPoint (org.apache.lucene.document.LongPoint)1 BinaryDocValues (org.apache.lucene.index.BinaryDocValues)1 DocValues (org.apache.lucene.index.DocValues)1 DocValuesType (org.apache.lucene.index.DocValuesType)1