예제 #1
0
 /**
  * 将分支数据转成Query逻辑
  *
  * @return
  */
 List<Query> toQueries(String fieldName) {
   List<Query> queries = new ArrayList<Query>(1);
   // 生成当前branch 的query
   if (lexeme != null) {
     queries.add(new TermQuery(new Term(fieldName, lexeme.getLexemeText())));
   }
   // 生成child branch 的query
   if (acceptedBranchs != null && acceptedBranchs.size() > 0) {
     if (acceptedBranchs.size() == 1) {
       Query onlyOneQuery = optimizeQueries(acceptedBranchs.get(0).toQueries(fieldName));
       if (onlyOneQuery != null) {
         queries.add(onlyOneQuery);
       }
     } else {
       BooleanQuery orQuery = new BooleanQuery();
       for (TokenBranch childBranch : acceptedBranchs) {
         Query childQuery = optimizeQueries(childBranch.toQueries(fieldName));
         if (childQuery != null) {
           orQuery.add(childQuery, Occur.SHOULD);
         }
       }
       if (orQuery.getClauses().length > 0) {
         queries.add(orQuery);
       }
     }
   }
   // 生成nextBranch的query
   if (nextBranch != null) {
     queries.addAll(nextBranch.toQueries(fieldName));
   }
   return queries;
 }
  @Test
  public void testQueryText() {

    Float boost = 0.7f;
    Object[] values = new Object[] {"houses", "cats"};

    Schema schema = schema().mapper("name", textMapper()).defaultAnalyzer("english").build();

    ContainsCondition condition = new ContainsCondition(boost, "name", values);
    Query query = condition.query(schema);
    assertNotNull("Query is not built", query);
    assertEquals("Query type is wrong", BooleanQuery.class, query.getClass());

    BooleanQuery booleanQuery = (BooleanQuery) query;
    assertEquals("Query boost is wrong", 0.7f, query.getBoost(), 0);
    BooleanClause[] clauses = booleanQuery.getClauses();
    assertEquals(
        "Query is wrong",
        "hous",
        ((TermQuery) clauses[0].getQuery()).getTerm().bytes().utf8ToString());
    assertEquals(
        "Query is wrong",
        "cat",
        ((TermQuery) clauses[1].getQuery()).getTerm().bytes().utf8ToString());
  }
 @Test
 public void testQueryPureNot() {
   Schema schema = schema().mapper("name", stringMapper()).build();
   BooleanCondition condition = bool().not(match("name", "jonathan")).boost(0.4).build();
   BooleanQuery query = (BooleanQuery) condition.query(schema);
   assertEquals(2, query.getClauses().length);
   assertEquals(0.4f, query.getBoost(), 0f);
 }
예제 #4
0
 public void testMatchAllDocs() throws Exception {
   QueryParserWrapper qp = new QueryParserWrapper("field", new WhitespaceAnalyzer());
   assertEquals(new MatchAllDocsQuery(), qp.parse("*:*"));
   assertEquals(new MatchAllDocsQuery(), qp.parse("(*:*)"));
   BooleanQuery bq = (BooleanQuery) qp.parse("+*:* -*:*");
   assertTrue(bq.getClauses()[0].getQuery() instanceof MatchAllDocsQuery);
   assertTrue(bq.getClauses()[1].getQuery() instanceof MatchAllDocsQuery);
 }
 @Test
 public void testQueryEmpty() {
   Schema schema = schema().build();
   BooleanCondition condition = bool().boost(0.4).build();
   BooleanQuery query = (BooleanQuery) condition.query(schema);
   assertEquals(0, query.getClauses().length);
   assertEquals(0.4f, query.getBoost(), 0f);
 }
  /**
   * Search, collecting hits with a {@link Collector}, and computing drill down and sideways counts.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  public DrillSidewaysResult search(DrillDownQuery query, Collector hitCollector)
      throws IOException {

    Map<String, Integer> drillDownDims = query.getDims();

    FacetsCollector drillDownCollector = new FacetsCollector();

    if (drillDownDims.isEmpty()) {
      // There are no drill-down dims, so there is no
      // drill-sideways to compute:
      searcher.search(query, MultiCollector.wrap(hitCollector, drillDownCollector));
      return new DrillSidewaysResult(buildFacetsResult(drillDownCollector, null, null), null);
    }

    BooleanQuery ddq = query.getBooleanQuery();
    BooleanClause[] clauses = ddq.getClauses();

    Query baseQuery;
    int startClause;
    if (clauses.length == drillDownDims.size()) {
      // TODO: we could optimize this pure-browse case by
      // making a custom scorer instead:
      baseQuery = new MatchAllDocsQuery();
      startClause = 0;
    } else {
      assert clauses.length == 1 + drillDownDims.size();
      baseQuery = clauses[0].getQuery();
      startClause = 1;
    }

    FacetsCollector[] drillSidewaysCollectors = new FacetsCollector[drillDownDims.size()];
    for (int i = 0; i < drillSidewaysCollectors.length; i++) {
      drillSidewaysCollectors[i] = new FacetsCollector();
    }

    Query[] drillDownQueries = new Query[clauses.length - startClause];
    for (int i = startClause; i < clauses.length; i++) {
      drillDownQueries[i - startClause] = clauses[i].getQuery();
    }
    DrillSidewaysQuery dsq =
        new DrillSidewaysQuery(
            baseQuery,
            drillDownCollector,
            drillSidewaysCollectors,
            drillDownQueries,
            scoreSubDocsAtOnce());
    searcher.search(dsq, hitCollector);

    return new DrillSidewaysResult(
        buildFacetsResult(
            drillDownCollector,
            drillSidewaysCollectors,
            drillDownDims.keySet().toArray(new String[drillDownDims.size()])),
        null);
  }
  public void testMatchAllDocs() throws Exception {
    AqpQueryParser qp = getParser();
    qp.setAnalyzer(new WhitespaceAnalyzer(TEST_VERSION_CURRENT));

    assertEquals(new MatchAllDocsQuery(), qp.parse("*:*", "field"));
    assertEquals(new MatchAllDocsQuery(), qp.parse("(*:*)", "field"));
    BooleanQuery bq = (BooleanQuery) qp.parse("+*:* -*:*", "field");
    assertTrue(bq.getClauses()[0].getQuery() instanceof MatchAllDocsQuery);
    assertTrue(bq.getClauses()[1].getQuery() instanceof MatchAllDocsQuery);
  }
 public void testMatchAllDocs() throws Exception {
   QueryParser qp =
       new QueryParser(
           TEST_VERSION_CURRENT,
           "field",
           new MockAnalyzer(random, MockTokenizer.WHITESPACE, false));
   assertEquals(new MatchAllDocsQuery(), qp.parse("*:*"));
   assertEquals(new MatchAllDocsQuery(), qp.parse("(*:*)"));
   BooleanQuery bq = (BooleanQuery) qp.parse("+*:* -*:*");
   assertTrue(bq.getClauses()[0].getQuery() instanceof MatchAllDocsQuery);
   assertTrue(bq.getClauses()[1].getQuery() instanceof MatchAllDocsQuery);
 }
 @Override
 public void write(DataOutput out) throws IOException {
   out.writeBoolean(query.isCoordDisabled());
   out.writeFloat(query.getBoost());
   out.writeInt(query.getMinimumNumberShouldMatch());
   BooleanClause[] clauses = query.getClauses();
   out.writeInt(clauses.length);
   for (int i = 0; i < clauses.length; i++) {
     BooleanClauseWritable booleanClauseWritable = new BooleanClauseWritable(clauses[i]);
     booleanClauseWritable.write(out);
   }
 }
예제 #10
0
 Filter getFacetFilter() {
   if (facetFilter == null) {
     BooleanQuery boolQuery = new BooleanQuery();
     for (FacetSelectionImpl selection : facetSelection.values()) {
       if (!selection.getFacetList().isEmpty()) {
         Query selectionGroupQuery = createSelectionGroupQuery(selection);
         boolQuery.add(selectionGroupQuery, BooleanClause.Occur.MUST);
       }
     }
     if (boolQuery.getClauses().length > 0) {
       this.facetFilter = new QueryWrapperFilter(boolQuery);
     }
   }
   return facetFilter;
 }
예제 #11
0
  private Query computeQuery(String patternString) {
    String upperPatternString = patternString.toUpperCase();

    boolean hasBooleanSpecifiers =
        upperPatternString.contains(" OR ")
            || upperPatternString.contains(" AND ") // $NON-NLS-1$ //$NON-NLS-2$
            || upperPatternString.contains(" NOT "); // $NON-NLS-1$

    if (!hasBooleanSpecifiers
        && defaultField.equals(FIELD_SUMMARY)
        && !containsSpecialCharacters(patternString)) {
      return new PrefixQuery(new Term(defaultField.getIndexKey(), patternString));
    }
    QueryParser qp =
        new QueryParser(
            Version.LUCENE_CURRENT, defaultField.getIndexKey(), TaskAnalyzer.instance());
    Query q;
    try {
      q = qp.parse(patternString);
    } catch (ParseException e) {
      return new PrefixQuery(new Term(defaultField.getIndexKey(), patternString));
    }

    // relax term clauses to be prefix clauses so that we get results close
    // to what we're expecting
    // from previous task list search
    if (q instanceof BooleanQuery) {
      BooleanQuery query = (BooleanQuery) q;
      for (BooleanClause clause : query.getClauses()) {
        if (clause.getQuery() instanceof TermQuery) {
          TermQuery termQuery = (TermQuery) clause.getQuery();
          clause.setQuery(new PrefixQuery(termQuery.getTerm()));
        }
        if (!hasBooleanSpecifiers) {
          clause.setOccur(Occur.MUST);
        }
      }
    } else if (q instanceof TermQuery) {
      return new PrefixQuery(((TermQuery) q).getTerm());
    }
    return q;
  }
  @Override
  protected void doAssertLuceneQuery(
      BoolQueryBuilder queryBuilder, Query query, QueryShardContext context) throws IOException {
    if (!queryBuilder.hasClauses()) {
      assertThat(query, instanceOf(MatchAllDocsQuery.class));
    } else {
      List<BooleanClause> clauses = new ArrayList<>();
      clauses.addAll(getBooleanClauses(queryBuilder.must(), BooleanClause.Occur.MUST, context));
      clauses.addAll(
          getBooleanClauses(queryBuilder.mustNot(), BooleanClause.Occur.MUST_NOT, context));
      clauses.addAll(getBooleanClauses(queryBuilder.should(), BooleanClause.Occur.SHOULD, context));
      clauses.addAll(getBooleanClauses(queryBuilder.filter(), BooleanClause.Occur.FILTER, context));

      if (clauses.isEmpty()) {
        assertThat(query, instanceOf(MatchAllDocsQuery.class));
      } else {
        assertThat(query, instanceOf(BooleanQuery.class));
        BooleanQuery booleanQuery = (BooleanQuery) query;
        assertThat(booleanQuery.isCoordDisabled(), equalTo(queryBuilder.disableCoord()));
        if (queryBuilder.adjustPureNegative()) {
          boolean isNegative = true;
          for (BooleanClause clause : clauses) {
            if (clause.isProhibited() == false) {
              isNegative = false;
              break;
            }
          }
          if (isNegative) {
            clauses.add(new BooleanClause(new MatchAllDocsQuery(), BooleanClause.Occur.MUST));
          }
        }
        assertThat(booleanQuery.clauses().size(), equalTo(clauses.size()));
        Iterator<BooleanClause> clauseIterator = clauses.iterator();
        for (BooleanClause booleanClause : booleanQuery.getClauses()) {
          assertThat(booleanClause, instanceOf(clauseIterator.next().getClass()));
        }
      }
    }
  }
  @Test
  public void testQuery() {

    Schema schema =
        schema()
            .mapper("name", stringMapper())
            .mapper("color", stringMapper())
            .mapper("country", stringMapper())
            .mapper("age", integerMapper())
            .defaultAnalyzer("default")
            .build();
    BooleanCondition condition =
        bool()
            .must(match("name", "jonathan"), range("age").lower(18).includeLower(true))
            .should(match("color", "green"), match("color", "blue"))
            .not(match("country", "england"))
            .boost(0.4f)
            .build();
    BooleanQuery query = (BooleanQuery) condition.query(schema);
    assertEquals(5, query.getClauses().length);
    assertEquals(0.4f, query.getBoost(), 0f);
  }
  @Test
  public void testQueryNumeric() {

    Float boost = 0.7f;
    Object[] values = new Object[] {1, 2, 3};

    Schema schema = schema().mapper("name", integerMapper()).build();

    ContainsCondition condition = new ContainsCondition(boost, "name", values);
    Query query = condition.query(schema);
    assertNotNull("Query is not built", query);
    assertEquals("Query type is wrong", BooleanQuery.class, query.getClass());

    BooleanQuery booleanQuery = (BooleanQuery) query;
    assertEquals("Boost is not set", 0.7f, query.getBoost(), 0);
    BooleanClause[] clauses = booleanQuery.getClauses();
    assertEquals("Query is wrong", values.length, clauses.length);
    for (int i = 0; i < values.length; i++) {
      NumericRangeQuery<?> numericRangeQuery = (NumericRangeQuery<?>) clauses[i].getQuery();
      assertEquals("Query is wrong", values[i], numericRangeQuery.getMin());
      assertEquals("Query is wrong", values[i], numericRangeQuery.getMax());
    }
  }
예제 #15
0
 private static void planBooleanQuery(final StringBuilder builder, final BooleanQuery query) {
   for (final BooleanClause clause : query.getClauses()) {
     builder.append(clause.getOccur());
     toPlan(builder, clause.getQuery());
   }
 }
예제 #16
0
  private void _includeIfUnique(
      BooleanQuery booleanQuery,
      boolean like,
      QueryParser queryParser,
      Query query,
      BooleanClause.Occur occur) {

    if (query instanceof TermQuery) {
      Set<Term> terms = new HashSet<Term>();

      TermQuery termQuery = (TermQuery) query;

      termQuery.extractTerms(terms);

      float boost = termQuery.getBoost();

      for (Term term : terms) {
        String termValue = term.text();

        if (like) {
          termValue = termValue.toLowerCase(queryParser.getLocale());

          term = term.createTerm(StringPool.STAR.concat(termValue).concat(StringPool.STAR));

          query = new WildcardQuery(term);
        } else {
          query = new TermQuery(term);
        }

        query.setBoost(boost);

        boolean included = false;

        for (BooleanClause booleanClause : booleanQuery.getClauses()) {
          if (query.equals(booleanClause.getQuery())) {
            included = true;
          }
        }

        if (!included) {
          booleanQuery.add(query, occur);
        }
      }
    } else if (query instanceof BooleanQuery) {
      BooleanQuery curBooleanQuery = (BooleanQuery) query;

      BooleanQuery containerBooleanQuery = new BooleanQuery();

      for (BooleanClause booleanClause : curBooleanQuery.getClauses()) {
        _includeIfUnique(
            containerBooleanQuery,
            like,
            queryParser,
            booleanClause.getQuery(),
            booleanClause.getOccur());
      }

      if (containerBooleanQuery.getClauses().length > 0) {
        booleanQuery.add(containerBooleanQuery, occur);
      }
    } else {
      boolean included = false;

      for (BooleanClause booleanClause : booleanQuery.getClauses()) {
        if (query.equals(booleanClause.getQuery())) {
          included = true;
        }
      }

      if (!included) {
        booleanQuery.add(query, occur);
      }
    }
  }
예제 #17
0
  @Override
  public Query parse() throws ParseException {
    // this will combine the results that are found for each
    // administrative level
    BooleanQuery allQuery = new BooleanQuery();

    // attempt to create a query on city (low level administrative division)
    String city = localParams.get(CITY);
    if (city != null) {
      city = city.toLowerCase();
      SchemaField nameField = req.getSchema().getField(NAME_FIELD);
      FieldType nameFieldType = nameField.getType();
      Query cityQuery = nameFieldType.getFieldQuery(this, nameField, city);
      allQuery.add(cityQuery, Occur.MUST);
    }

    // attempt to create a query on state (mid level administrative division)
    String state = localParams.get(STATE);
    if (state != null) {
      state = state.toLowerCase();
      SchemaField stateField = req.getSchema().getField(STATE_FIELD);
      FieldType stateFieldType = stateField.getType();
      Query stateQuery = stateFieldType.getFieldQuery(this, stateField, state);
      allQuery.add(stateQuery, Occur.MUST);
    }

    // attempt to create a query on city (high level administrative division)
    String country = localParams.get(COUNTRY);
    if (country != null) {
      country = country.toLowerCase();
      SchemaField countryField = req.getSchema().getField(COUNTRY_FIELD);
      FieldType countryFieldType = countryField.getType();
      Query countryQuery = countryFieldType.getFieldQuery(this, countryField, country);
      allQuery.add(countryQuery, Occur.MUST);
    }

    String latitude = null;
    String longitude = null;

    // no location provided, computer user's location via reverse-ip lookup
    if (allQuery.getClauses().length == 0) {
      HttpServletRequest httpreq = req.getHttpServletRequest();
      String ip = httpreq.getRemoteAddr();

      LatLng currLoc = geoTargeter.getCurrentLocation(ip);

      if (currLoc != null) {
        latitude = Double.toString(currLoc.getLat());
        longitude = Double.toString(currLoc.getLng());
      }
    } else {
      SolrIndexSearcher searcher = req.getSearcher();
      Document geocodeDoc = null;

      try {
        Sort s = new Sort(new SortField(POPULATION_FIELD, SortField.LONG, true));
        DocList docs = searcher.getDocList(allQuery, new ArrayList<Query>(), s, 0, 1, 0);

        if (docs == null) return query;

        DocIterator iter = docs.iterator();
        int geocodeDocId = iter.nextDoc();
        geocodeDoc = searcher.doc(geocodeDocId);
      } catch (Exception e) {
        e.printStackTrace();
        return query;
      }
      latitude = geocodeDoc.get("latitude");
      longitude = geocodeDoc.get("longitude");
    }

    // combine the spatial and free-text queries
    BooleanQuery finalQuery = new BooleanQuery();

    // if no location is provided and user's location cannot be determined,
    // do not search location
    if (latitude != null && longitude != null) {
      String distance = localParams.get(DISTANCE);

      try {
        Double.parseDouble(distance);
      } catch (Exception e) {
        distance = SEARCH_RADIUS;
      }

      SpatialFilterQParserPlugin spatialFilter = new SpatialFilterQParserPlugin();
      ModifiableSolrParams spatialParams = new ModifiableSolrParams();
      spatialParams.add(SpatialParams.POINT, latitude + "," + longitude);
      spatialParams.add(SpatialParams.DISTANCE, distance);
      spatialParams.add(CommonParams.FL, LOCATION_FIELD);
      Query spatialQuery =
          spatialFilter.createParser(qstr, spatialParams, spatialParams, req).parse();
      finalQuery.add(spatialQuery, Occur.MUST);
    }

    // get results from default LuceneQParser
    Query defQuery = new LuceneQParserPlugin().createParser(qstr, localParams, params, req).parse();

    finalQuery.add(defQuery, Occur.MUST);

    return finalQuery;
  }
  /**
   * Construct the query (using spans). This method will be called recursively.
   *
   * @param q Query
   * @param scope Author, affiliation, or Reference
   * @param level Used only for formatting (indentation) the level of recursion
   * @param andSpans ArrayList of Spans that should be 'and'
   * @param orSpans ArrayList of Spans that should be 'or'
   * @param notSpans ArrayList of Spans that should be 'not'
   * @return SpanQuery
   */
  private SpanQuery buildQuery_recursive(
      Query q,
      String scope,
      int level,
      ArrayList<SpanQuery> andSpans,
      ArrayList<SpanQuery> orSpans,
      ArrayList<SpanQuery> notSpans) {

    BooleanQuery castQuery = (BooleanQuery) q;
    String subscope = null;

    for (BooleanClause clause : castQuery.getClauses()) {

      Class queryclazz = clause.getQuery().getClass();

      System.out.println(
          repeat(' ', level)
              + "["
              + queryclazz
              + "]["
              + clause.getOccur()
              + "] "
              + clause.toString());

      if (queryclazz == BooleanQuery.class) {

        System.out.println("Number of Clauses is " + castQuery.clauses().size());
        System.out.println("Minimum Number to Match is " + castQuery.getMinimumNumberShouldMatch());

        if (subscope == null) {

          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(
                buildQuery_recursive(
                    clause.getQuery(),
                    scope,
                    level + 1,
                    new ArrayList<SpanQuery>(),
                    new ArrayList<SpanQuery>(),
                    new ArrayList<SpanQuery>()));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(
                buildQuery_recursive(
                    clause.getQuery(),
                    scope,
                    level + 1,
                    new ArrayList<SpanQuery>(),
                    new ArrayList<SpanQuery>(),
                    new ArrayList<SpanQuery>()));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(
                buildQuery_recursive(
                    clause.getQuery(),
                    scope,
                    level + 1,
                    new ArrayList<SpanQuery>(),
                    new ArrayList<SpanQuery>(),
                    new ArrayList<SpanQuery>()));
          }

        } else {

          ArrayList<SpanQuery> subscopeQuery = new ArrayList<SpanQuery>();
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.BEG_TAG))));
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.END_TAG))));
          subscopeQuery.add(
              buildQuery_recursive(
                  clause.getQuery(),
                  scope,
                  level + 1,
                  new ArrayList<SpanQuery>(),
                  new ArrayList<SpanQuery>(),
                  new ArrayList<SpanQuery>()));
          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          }
        }

      } else if (queryclazz == TermQuery.class) {

        TermQuery tq = (TermQuery) clause.getQuery();

        if (tq.getTerm().field().compareTo(SUBSCOPE_FIELD) == 0) {

          // Set the subscope
          subscope = tq.getTerm().text();

          // Need to add a term here (otherwise we have problems)
          WildcardQuery wildcard = new WildcardQuery(new Term(scope, "*"));
          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(new SpanMultiTermQueryWrapper<WildcardQuery>(wildcard));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(new SpanMultiTermQueryWrapper<WildcardQuery>(wildcard));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            notSpans.add(new SpanMultiTermQueryWrapper<WildcardQuery>(wildcard));
          }

        } else if (subscope == null) {

          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(buildTermQuery(scope, tq));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(buildTermQuery(scope, tq));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            notSpans.add(buildTermQuery(scope, tq));
          }

        } else {

          ArrayList<SpanQuery> subscopeQuery = new ArrayList<SpanQuery>();
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.BEG_TAG))));
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.END_TAG))));
          subscopeQuery.add(buildTermQuery(scope, tq));
          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          }
        }

      } else if (queryclazz == WildcardQuery.class) {

        if (subscope == null) {

          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(buildWildcardQuery(scope, clause.getQuery()));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(buildWildcardQuery(scope, clause.getQuery()));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(buildWildcardQuery(scope, clause.getQuery()));
          }

        } else {

          ArrayList<SpanQuery> subscopeQuery = new ArrayList<SpanQuery>();
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.BEG_TAG))));
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.END_TAG))));
          subscopeQuery.add(buildWildcardQuery(scope, clause.getQuery()));
          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          }
        }

      } else if (queryclazz == PrefixQuery.class) {

        if (subscope == null) {

          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(buildPrefixQuery(scope, clause.getQuery()));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(buildPrefixQuery(scope, clause.getQuery()));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(buildPrefixQuery(scope, clause.getQuery()));
          }

        } else {

          ArrayList<SpanQuery> subscopeQuery = new ArrayList<SpanQuery>();
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.BEG_TAG))));
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.END_TAG))));
          subscopeQuery.add(buildPrefixQuery(scope, clause.getQuery()));
          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          }
        }

      } else if (queryclazz == PhraseQuery.class) {

        if (subscope == null) {

          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(buildPhraseQuery(scope, clause.getQuery()));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(buildPhraseQuery(scope, clause.getQuery()));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(buildPhraseQuery(scope, clause.getQuery()));
          }

        } else {

          ArrayList<SpanQuery> subscopeQuery = new ArrayList<SpanQuery>();
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.BEG_TAG))));
          subscopeQuery.add(
              new SpanTermQuery(new Term(scope, getTag(scope, subscope, TAG_TYPE.END_TAG))));
          subscopeQuery.add(buildPhraseQuery(scope, clause.getQuery()));
          if (clause.getOccur() == BooleanClause.Occur.MUST) {
            andSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.SHOULD) {
            orSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          } else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT) {
            // FIX
            notSpans.add(
                new SpanBetweenQuery(subscopeQuery.toArray(new SpanQuery[subscopeQuery.size()])));
          }
        }

      } else {

        System.out.println("[" + q.getClass() + "]");
      }
    }

    ArrayList<SpanQuery> includeSpans = new ArrayList<SpanQuery>();
    ;

    // Add the 'and' queries to the includeSpans (if there were any)
    if (!andSpans.isEmpty()) {
      if (andSpans.size() > 1) {
        includeSpans.add(new SpanAndQuery(andSpans.toArray(new SpanQuery[andSpans.size()])));
      } else {
        includeSpans.add(andSpans.get(0));
      }
    }

    // Add the 'or' queries to the includeSpans (if there were any)
    if (!orSpans.isEmpty()) {
      includeSpans.add(new SpanOrQuery(orSpans.toArray(new SpanQuery[orSpans.size()])));
    }

    // Exclude the 'not' queries from the includeSpans (if there were any)
    if (!notSpans.isEmpty()) {
      if (includeSpans.size() > 1) {
        if (notSpans.size() > 1) {
          return new SpanNotQuery(
              new SpanAndQuery(includeSpans.toArray(new SpanQuery[includeSpans.size()])),
              new SpanAndQuery(notSpans.toArray(new SpanQuery[notSpans.size()])));
        } else {
          return new SpanNotQuery(
              new SpanAndQuery(includeSpans.toArray(new SpanQuery[includeSpans.size()])),
              notSpans.get(0));
        }
      } else {
        if (notSpans.size() > 1) {
          return new SpanNotQuery(
              includeSpans.get(0),
              new SpanAndQuery(notSpans.toArray(new SpanQuery[notSpans.size()])));
        } else {
          return new SpanNotQuery(includeSpans.get(0), notSpans.get(0));
        }
      }
    } else {
      if (includeSpans.size() > 1) {
        return new SpanAndQuery(includeSpans.toArray(new SpanQuery[includeSpans.size()]));
      } else {
        return includeSpans.get(0);
      }
    }
  }