/** * Adds for every field in {@link IIndexTypeConf} a {@link TermQuery}, {@link PrefixQuery} and * a {@link FuzzyQuery} with a suitable boost relative to the given base boost. * * @param indexType the type in which should be searched. * @param search the search text. * @param subQuery the {@link BooleanQuery} to add the sub queries. * @param baseBoost highest possible boost of the query. The more the match is exact * than a bigger boost will be used. */ private static void addSearchTermQueries(final IIndexTypeConf indexType, final String search, final BooleanQuery subQuery, final float baseBoost) { for(final IIndexFieldConf<?> field : indexType.getFields()) { final Term term = new Term(field.getName(), search); final TermQuery exactQuery = new TermQuery(term); exactQuery.setBoost(baseBoost); subQuery.add(exactQuery, Occur.SHOULD); final PrefixQuery pfQuery = new PrefixQuery(term); pfQuery.setBoost(0.7f*baseBoost); subQuery.add(pfQuery, Occur.SHOULD); final FuzzyQuery fuzzyQuery = new FuzzyQuery(term); fuzzyQuery.setBoost(0.5f*baseBoost); subQuery.add(fuzzyQuery, Occur.SHOULD); } }
private Query getFuzzyQuerySingle(String field, String termStr, String minSimilarity) throws ParseException { currentFieldType = context.fieldMapper(field); if (currentFieldType != null) { try { BytesRef term = termStr == null ? null : getAnalyzer().normalize(field, termStr); return currentFieldType.fuzzyQuery(term, Fuzziness.build(minSimilarity), getFuzzyPrefixLength(), settings.fuzzyMaxExpansions(), FuzzyQuery.defaultTranspositions); } catch (RuntimeException e) { if (settings.lenient()) { return null; } throw e; } } return super.getFuzzyQuery(field, termStr, Float.parseFloat(minSimilarity)); }
/** * Dispatches to Lucene's SimpleQueryParser's newFuzzyQuery, optionally * lowercasing the term first */ @Override public Query newFuzzyQuery(String text, int fuzziness) { BooleanQuery.Builder bq = new BooleanQuery.Builder(); bq.setDisableCoord(true); for (Map.Entry<String,Float> entry : weights.entrySet()) { final String fieldName = entry.getKey(); try { final BytesRef term = getAnalyzer().normalize(fieldName, text); Query query = new FuzzyQuery(new Term(fieldName, term), fuzziness); bq.add(wrapWithBoost(query, entry.getValue()), BooleanClause.Occur.SHOULD); } catch (RuntimeException e) { rethrowUnlessLenient(e); } } return super.simplify(bq.build()); }
public void testToQueryWithStringField() throws IOException { assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); String query = "{\n" + " \"fuzzy\":{\n" + " \"" + STRING_FIELD_NAME + "\":{\n" + " \"value\":\"sh\",\n" + " \"fuzziness\": \"AUTO\",\n" + " \"prefix_length\":1,\n" + " \"boost\":2.0\n" + " }\n" + " }\n" + "}"; Query parsedQuery = parseQuery(query).toQuery(createShardContext()); assertThat(parsedQuery, instanceOf(BoostQuery.class)); BoostQuery boostQuery = (BoostQuery) parsedQuery; assertThat(boostQuery.getBoost(), equalTo(2.0f)); assertThat(boostQuery.getQuery(), instanceOf(FuzzyQuery.class)); FuzzyQuery fuzzyQuery = (FuzzyQuery) boostQuery.getQuery(); assertThat(fuzzyQuery.getTerm(), equalTo(new Term(STRING_FIELD_NAME, "sh"))); assertThat(fuzzyQuery.getMaxEdits(), equalTo(Fuzziness.AUTO.asDistance("sh"))); assertThat(fuzzyQuery.getPrefixLength(), equalTo(1)); }
/** * Checks if the given phrase is banned with fuzzy matching. * * @param phrase * phrase to check * @return <code>true</code> if phrase is banned */ public boolean isFuzzyPhraseBanned(String phrase) { if (phrase != null) { String[] parts = phrase.split(" "); if (parts != null) { for (String part : parts) { FuzzyQuery query = new FuzzyQuery(new Term(LUCENE_FIELD_NAME, part), 2); try { ScoreDoc[] hits = indexSearcher.search(query, null, 1).scoreDocs; if (hits.length > 0) { return true; } } catch (Exception ex) { LOG.error("Error running query", ex); } } } } return false; }
/** test a fuzzy query */ public void testFuzzy() throws Exception { Query regular = new TermQuery(new Term("field", "foobar")); Query expected = new FuzzyQuery(new Term("field", "foobar"), 2); assertEquals(expected, parse("foobar~2")); assertEquals(regular, parse("foobar~")); assertEquals(regular, parse("foobar~a")); assertEquals(regular, parse("foobar~1a")); BooleanQuery bool = new BooleanQuery(); FuzzyQuery fuzzy = new FuzzyQuery(new Term("field", "foo"), LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE); bool.add(fuzzy, Occur.MUST); bool.add(new TermQuery(new Term("field", "bar")), Occur.MUST); assertEquals(bool, parse("foo~" + LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE + 1 + " bar")); }
public void testNoSuchMultiTermsInSpanFirst() throws Exception { //this hasn't been a problem FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false); SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<>(fuzzyNoSuch); SpanQuery spanFirst = new SpanFirstQuery(spanNoSuch, 10); assertEquals(0, searcher.search(spanFirst, 10).totalHits); WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*")); SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<>(wcNoSuch); spanFirst = new SpanFirstQuery(spanWCNoSuch, 10); assertEquals(0, searcher.search(spanFirst, 10).totalHits); RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch")); SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<>(rgxNoSuch); spanFirst = new SpanFirstQuery(spanRgxNoSuch, 10); assertEquals(0, searcher.search(spanFirst, 10).totalHits); PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch")); SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<>(prfxNoSuch); spanFirst = new SpanFirstQuery(spanPrfxNoSuch, 10); assertEquals(0, searcher.search(spanFirst, 10).totalHits); }
private boolean containsClause(Query query, String field, String value, int boost, boolean fuzzy) { if(query instanceof BooleanQuery) { return containsClause((BooleanQuery)query, field, value, boost, fuzzy); } if(query instanceof DisjunctionMaxQuery) { return containsClause((DisjunctionMaxQuery)query, field, value, boost, fuzzy); } if(query instanceof TermQuery && !fuzzy) { return containsClause((TermQuery)query, field, value, boost); } if(query instanceof FuzzyQuery && fuzzy) { return containsClause((FuzzyQuery)query, field, value, boost); } return false; }
protected String toString(FuzzyQuery fuzzyQuery, String field) { final StringBuilder buffer = new StringBuilder(); Term term = fuzzyQuery.getTerm(); int maxEdits = fuzzyQuery.getMaxEdits(); if (!term.field().equals(field)) { buffer.append(term.field()); buffer.append(":"); } buffer.append(term.text()); buffer.append('~'); buffer.append(Integer.toString(maxEdits)); return buffer.toString(); }
@Test public void testFuzzyQuery() throws Exception { buildIndex(fts); try { String userInput = "title"; FuzzyQuery luceneQuery = new FuzzyQuery(new Term("title", userInput), 0.4f); log.debug("Query=" + luceneQuery.toString()); FullTextQuery ftq = fts.createFullTextQuery(luceneQuery, Dvd.class); List<Dvd> results = ftq.list(); Assertions.assertThat(results.size()).isEqualTo(5); // Assertions.assertThat(results.get(0).getTitle()).isEqualTo(titles[0]); for (Dvd dvd : results) { log.debug("Title=" + dvd.getTitle()); } } finally { for (Object element : fts.createQuery("from " + Dvd.class.getName()).list()) { fts.delete(element); } } }
public void testFuzzy() throws Exception { indexSingleFieldDocs(new Field[] { new Field("contents", "fuzzy", Field.Store.YES, Field.Index.ANALYZED), new Field("contents", "wuzzy", Field.Store.YES, Field.Index.ANALYZED) }); IndexSearcher searcher = new IndexSearcher(directory); Query query = new FuzzyQuery(new Term("contents", "wuzza")); TopDocs matches = searcher.search(query, 10); assertEquals("both close enough", 2, matches.totalHits); assertTrue("wuzzy closer than fuzzy", matches.scoreDocs[0].score != matches.scoreDocs[1].score); StoredDocument doc = searcher.doc(matches.scoreDocs[0].doc); assertEquals("wuzza bear", "wuzzy", doc.get("contents")); searcher.close(); }
private void findSimilarWordsTo(DirectoryReader reader, IndexSearcher searcher, String word) throws IOException { FuzzyQuery query = new FuzzyQuery(new Term("word", word), 2); // a missing char counts as a distance of 2 TopDocs topDocs = searcher.search(query, 10); //System.out.println(topDocs.totalHits + " hits for " + word); List<SimWord> simWords = findSimilarWordsFor(reader, word, topDocs); //System.out.println(word + " -> " + String.join(", ", simWords)); for (SimWord simWord : simWords) { if (word.length() == simWord.word.length()) { int firstDiffPos = getDiffPos(simWord.word.toLowerCase(), word.toLowerCase()); try { float dist = keyDistance.getDistance(word.charAt(firstDiffPos), simWord.word.charAt(firstDiffPos)); System.out.println(dist + "; " + word + "; " + simWord); } catch (Exception e) { System.err.println("Could not get distance between '" + word + "' and '" + simWord + "':"); e.printStackTrace(); } } else { // TODO: these need to be handled, too //System.out.println("-; " + word + "; " + simWord.word); } } }
@Override protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) { String text = term.text(); int numEdits = FuzzyQuery.floatToEdits(minimumSimilarity, text.codePointCount(0, text.length())); FuzzyQuery query = new FuzzyQuery(term, numEdits, prefixLength, settings.fuzzyMaxExpansions(), FuzzyQuery.defaultTranspositions); QueryParsers.setRewriteMethod(query, settings.fuzzyRewriteMethod()); return query; }
@Override public final Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) { failIfNotIndexed(); return new FuzzyQuery(new Term(name(), indexedValueForSearch(value)), fuzziness.asDistance(BytesRefs.toString(value)), prefixLength, maxExpansions, transpositions); }
@Override protected void doAssertLuceneQuery(MultiMatchQueryBuilder queryBuilder, Query query, SearchContext context) throws IOException { // we rely on integration tests for deeper checks here assertThat(query, either(instanceOf(BoostQuery.class)).or(instanceOf(TermQuery.class)).or(instanceOf(AllTermQuery.class)) .or(instanceOf(BooleanQuery.class)).or(instanceOf(DisjunctionMaxQuery.class)) .or(instanceOf(FuzzyQuery.class)).or(instanceOf(MultiPhrasePrefixQuery.class)) .or(instanceOf(MatchAllDocsQuery.class)).or(instanceOf(ExtendedCommonTermsQuery.class)) .or(instanceOf(MatchNoDocsQuery.class)).or(instanceOf(PhraseQuery.class)) .or(instanceOf(LegacyNumericRangeQuery.class)) .or(instanceOf(PointRangeQuery.class)).or(instanceOf(IndexOrDocValuesQuery.class))); }
public void testFuzzyQuery() { MappedFieldType ft = createDefaultFieldType(); ft.setName("field"); ft.setIndexOptions(IndexOptions.DOCS); assertEquals(new FuzzyQuery(new Term("field","foo"), 2, 1, 50, true), ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); }
/** * Get the minimal similarity for fuzzy queries. */ @Override public float getFuzzyMinSim() { FuzzyConfig fuzzyConfig = getQueryConfigHandler().get(ConfigurationKeys.FUZZY_CONFIG); if (fuzzyConfig == null) { return FuzzyQuery.defaultMinSimilarity; } else { return fuzzyConfig.getMinSimilarity(); } }
/** * Get the prefix length for fuzzy queries. * * @return Returns the fuzzyPrefixLength. */ @Override public int getFuzzyPrefixLength() { FuzzyConfig fuzzyConfig = getQueryConfigHandler().get(ConfigurationKeys.FUZZY_CONFIG); if (fuzzyConfig == null) { return FuzzyQuery.defaultPrefixLength; } else { return fuzzyConfig.getPrefixLength(); } }
@Override public FuzzyQuery build(QueryNode queryNode) throws QueryNodeException { FuzzyQueryNode fuzzyNode = (FuzzyQueryNode) queryNode; String text = fuzzyNode.getTextAsString(); int numEdits = FuzzyQuery.floatToEdits(fuzzyNode.getSimilarity(), text.codePointCount(0, text.length())); return new FuzzyQuery(new Term(fuzzyNode.getFieldAsString(), fuzzyNode .getTextAsString()), numEdits, fuzzyNode .getPrefixLength()); }
/** * Factory method to generate a fuzzy query. */ protected Query newFuzzyQuery(String text, int fuzziness) { BooleanQuery bq = new BooleanQuery(true); for (Map.Entry<String,Float> entry : weights.entrySet()) { Query q = new FuzzyQuery(new Term(entry.getKey(), text), fuzziness); if (q != null) { q.setBoost(entry.getValue()); bq.add(q, BooleanClause.Occur.SHOULD); } } return simplify(bq); }
private static QueryBuilder fuzzy(Query q) { QueryBuilder qb; String field = ((FuzzyQuery) q).getTerm().field(); String value = ((FuzzyQuery) q).getTerm().text(); if (StringUtils.isBlank(field)) { qb = multiMatchQuery(value); } else if (nestedMode() && field.matches(PROPS_REGEX)) { qb = nestedPropsQuery(keyValueBoolQuery(field, fuzzyQuery(getValueFieldName(value), value))); } else { qb = fuzzyQuery(field, value); } return qb; }
public static ParsedOptions parse(MultiMatchQueryBuilder.Type matchType, @Nullable Map options) throws IllegalArgumentException { if (options == null) { options = Collections.emptyMap(); } else { // need a copy. Otherwise manipulations on a shared option will lead to strange race conditions. options = new HashMap(options); } ParsedOptions parsedOptions = new ParsedOptions( floatValue(options, OPTIONS.BOOST, null), analyzer(options.remove(OPTIONS.ANALYZER)), zeroTermsQuery(options.remove(OPTIONS.ZERO_TERMS_QUERY)), intValue(options, OPTIONS.MAX_EXPANSIONS, FuzzyQuery.defaultMaxExpansions), fuzziness(options.remove(OPTIONS.FUZZINESS)), intValue(options, OPTIONS.PREFIX_LENGTH, FuzzyQuery.defaultPrefixLength), transpositions(options.remove(OPTIONS.FUZZY_TRANSPOSITIONS)) ); switch (matchType.matchQueryType()) { case BOOLEAN: parsedOptions.commonTermsCutoff(floatValue(options, OPTIONS.CUTOFF_FREQUENCY, null)); parsedOptions.operator(operator(options.remove(OPTIONS.OPERATOR))); parsedOptions.minimumShouldMatch(minimumShouldMatch(options.remove(OPTIONS.MINIMUM_SHOULD_MATCH))); break; case PHRASE: parsedOptions.phraseSlop(intValue(options, OPTIONS.SLOP, 0)); parsedOptions.tieBreaker(floatValue(options, OPTIONS.TIE_BREAKER, null)); break; case PHRASE_PREFIX: parsedOptions.phraseSlop(intValue(options, OPTIONS.SLOP, 0)); parsedOptions.tieBreaker(floatValue(options, OPTIONS.TIE_BREAKER, null)); parsedOptions.rewrite(rewrite(options.remove(OPTIONS.REWRITE))); break; } if (!options.isEmpty()) { raiseIllegalOptions(matchType, options); } return parsedOptions; }
private Query getFuzzyQuerySingle(String field, String termStr, String minSimilarity) throws ParseException { currentFieldType = parseContext.fieldMapper(field); if (currentFieldType != null) { try { return currentFieldType.fuzzyQuery(termStr, Fuzziness.build(minSimilarity), fuzzyPrefixLength, settings.fuzzyMaxExpansions(), FuzzyQuery.defaultTranspositions); } catch (RuntimeException e) { if (settings.lenient()) { return null; } throw e; } } return super.getFuzzyQuery(field, termStr, Float.parseFloat(minSimilarity)); }
private List<String> getUsingFuzzySearch(String searchQuery) throws IOException { Query query = new FuzzyQuery(new Term(WORD_FIELD, searchQuery), 2, 0); List<String> foundWords = new ArrayList<>(); TopDocs rs = searcher.search(query, 2); for (ScoreDoc docRef : rs.scoreDocs) { Document docHit = searcher.doc(docRef.doc); foundWords.add(docHit.get(WORD_FIELD)); } return foundWords; }
@SuppressWarnings("unchecked") @Transactional(readOnly = true) public Page<Article> search(String keyword, Pageable pageable) { if (StringUtils.isEmpty(keyword)) { return new Page<Article>(); } if (pageable == null) { pageable = new Pageable(); } try { String text = QueryParser.escape(keyword); QueryParser titleParser = new QueryParser(Version.LUCENE_35, "title", new IKAnalyzer()); titleParser.setDefaultOperator(QueryParser.AND_OPERATOR); Query titleQuery = titleParser.parse(text); FuzzyQuery titleFuzzyQuery = new FuzzyQuery(new Term("title", text), FUZZY_QUERY_MINIMUM_SIMILARITY); Query contentQuery = new TermQuery(new Term("content", text)); Query isPublicationQuery = new TermQuery(new Term("isPublication", "true")); BooleanQuery textQuery = new BooleanQuery(); BooleanQuery query = new BooleanQuery(); textQuery.add(titleQuery, Occur.SHOULD); textQuery.add(titleFuzzyQuery, Occur.SHOULD); textQuery.add(contentQuery, Occur.SHOULD); query.add(isPublicationQuery, Occur.MUST); query.add(textQuery, Occur.MUST); FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, Article.class); fullTextQuery.setSort(new Sort(new SortField[] { new SortField("isTop", SortField.STRING, true), new SortField(null, SortField.SCORE), new SortField("createDate", SortField.LONG, true) })); fullTextQuery.setFirstResult((pageable.getPageNumber() - 1) * pageable.getPageSize()); fullTextQuery.setMaxResults(pageable.getPageSize()); return new Page<Article>(fullTextQuery.getResultList(), fullTextQuery.getResultSize(), pageable); } catch (ParseException e) { e.printStackTrace(); } return new Page<Article>(); }
private static Query queryFromString(Analyzer analyzer, String searchText, int fuzzy) { if (searchText != null && !searchText.isEmpty()) { BooleanQuery.Builder b = new BooleanQuery.Builder(); try (TokenStream stream = analyzer.tokenStream(FIELD_TERM, searchText)) { CharTermAttribute termAtt = stream.addAttribute(CharTermAttribute.class); stream.reset(); while (stream.incrementToken()) { String s = termAtt.toString(); Term term = new Term("term", s); Query tq = s.length() > MINIMUM_CHARS_FOR_FUZZY_SEARCH && fuzzy > 0 ? new FuzzyQuery(term, fuzzy) : new TermQuery(term); if (s.length() >= MINIMUM_CHARS_FOR_PREFIX_SEARCH) { PrefixQuery pq = new PrefixQuery(new Term("term", s)); pq.setRewriteMethod(PrefixQuery.SCORING_BOOLEAN_REWRITE); BooleanQuery bq = new BooleanQuery.Builder().add(tq, Occur.SHOULD).add(pq, Occur.SHOULD).build(); b.add(bq, Occur.MUST); } else { b.add(tq,Occur.MUST); } } stream.end(); } catch (IOException e) { e.printStackTrace(); } return b.build(); } return null; }
@SuppressWarnings("unchecked") public static String queryToString(Query luceneQuery) { StringBuilder sb = new StringBuilder(); if (luceneQuery instanceof BooleanQuery) { sb.append(formatBooleanQuery((BooleanQuery) luceneQuery)); } else if (luceneQuery instanceof TermQuery) { sb.append(formatTermQuery((TermQuery) luceneQuery)); } else if (luceneQuery instanceof RawLuceneQuery) { sb.append(formatRawLuceneQuery((RawLuceneQuery) luceneQuery)); } else if (luceneQuery instanceof FuzzyQuery) { sb.append(formatFuzzyQuery((FuzzyQuery) luceneQuery)); } else if (luceneQuery instanceof PrefixQuery) { sb.append(formatPrefixQuery((PrefixQuery) luceneQuery)); } else if (luceneQuery instanceof WildcardQuery) { sb.append(formatWildcardQuery((WildcardQuery) luceneQuery)); } else if (luceneQuery instanceof NumericRangeQuery) { sb.append(formatNumericRangeQuery((NumericRangeQuery<? extends Number>) luceneQuery)); } else if (luceneQuery instanceof IToQueryStringAwareLuceneQuery) { sb.append(((IToQueryStringAwareLuceneQuery) luceneQuery).toQueryString()); } else if (luceneQuery instanceof BoostQuery) { sb.append(queryToString(((BoostQuery) luceneQuery).getQuery())); sb.append(BOOST_PARAMETER_PREFIX); sb.append(((BoostQuery) luceneQuery).getBoost()); } else { throw new IllegalStateException(String.format("Query of type %1$s not supported", luceneQuery.getClass().getName())); } return sb.toString(); }
private static String formatFuzzyQuery(FuzzyQuery fuzzyQuery) { StringBuilder sb = new StringBuilder(); Term term = fuzzyQuery.getTerm(); if (StringUtils.hasText(term.field())) { sb.append(term.field()); sb.append(":"); } sb.append(QueryParser.escape(term.text())) .append(FUZZY_PARAMETER_SUFFIX) .append(fuzzyQuery.getMaxEdits()); return sb.toString(); }
public static Query createFuzzyQuery(final String field, final String value) { return new Query() { @Override public org.apache.lucene.search.Query getLuceneQuery(Schema schema) { validateType(field, schema, JsonNode.Type.STRING); return new FuzzyQuery(new Term(field, value)); } }; }
public void testFuzzy() throws Exception { FuzzyQuery fq = new FuzzyQuery(new Term("field", "broan")); SpanQuery sfq = new SpanMultiTermQueryWrapper<>(fq); // will not match quick brown fox SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 3, 6); assertEquals(2, searcher.search(sprq, 10).totalHits); }
public void testFuzzy2() throws Exception { // maximum of 1 term expansion FuzzyQuery fq = new FuzzyQuery(new Term("field", "broan"), 1, 0, 1, false); SpanQuery sfq = new SpanMultiTermQueryWrapper<>(fq); // will only match jumps over lazy broun dog SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 0, 100); assertEquals(1, searcher.search(sprq, 10).totalHits); }
public void testNoSuchMultiTermsInNear() throws Exception { //test to make sure non existent multiterms aren't throwing null pointer exceptions FuzzyQuery fuzzyNoSuch = new FuzzyQuery(new Term("field", "noSuch"), 1, 0, 1, false); SpanQuery spanNoSuch = new SpanMultiTermQueryWrapper<>(fuzzyNoSuch); SpanQuery term = new SpanTermQuery(new Term("field", "brown")); SpanQuery near = new SpanNearQuery(new SpanQuery[]{term, spanNoSuch}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); //flip order near = new SpanNearQuery(new SpanQuery[]{spanNoSuch, term}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); WildcardQuery wcNoSuch = new WildcardQuery(new Term("field", "noSuch*")); SpanQuery spanWCNoSuch = new SpanMultiTermQueryWrapper<>(wcNoSuch); near = new SpanNearQuery(new SpanQuery[]{term, spanWCNoSuch}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); RegexpQuery rgxNoSuch = new RegexpQuery(new Term("field", "noSuch")); SpanQuery spanRgxNoSuch = new SpanMultiTermQueryWrapper<>(rgxNoSuch); near = new SpanNearQuery(new SpanQuery[]{term, spanRgxNoSuch}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); PrefixQuery prfxNoSuch = new PrefixQuery(new Term("field", "noSuch")); SpanQuery spanPrfxNoSuch = new SpanMultiTermQueryWrapper<>(prfxNoSuch); near = new SpanNearQuery(new SpanQuery[]{term, spanPrfxNoSuch}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); //test single noSuch near = new SpanNearQuery(new SpanQuery[]{spanPrfxNoSuch}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); //test double noSuch near = new SpanNearQuery(new SpanQuery[]{spanPrfxNoSuch, spanPrfxNoSuch}, 1, true); assertEquals(0, searcher.search(near, 10).totalHits); }