Loading the parity record
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Parity / Lucene
Every number on this page was produced by running both implementations over the same cases: the real lucene package pinned at 9.11.1 answers first, and its answer is the expectation the Go port is held to. Nothing is a hand-written expectation, so a new upstream release re-scores the port on its own. See Lucene for the port's own documentation. Source: github.com/malcolmston/lucene.
Not a generic diagram: every node below names an artefact of this harness — the pinned package it installed, the runner files it started, the case files it streamed, and the counts it wrote out.
| Case group | Cases | Match | Mismatch | Group parity |
|---|---|---|---|---|
| query | 80 | 73 | 7 | 91.3% |
| parser | 46 | 29 | 17 | 63.0% |
| analyzer | 44 | 20 | 24 | 45.5% |
| ngram | 23 | 17 | 6 | 73.9% |
| util | 23 | 20 | 3 | 87.0% |
| index | 21 | 20 | 1 | 95.2% |
Every exported symbol of the upstream package, and what the port offers for it. The upstream list is derived mechanically, never from a README: unzip -l lucene-core-9.11.1.jar '*.class' | grep -c '\.class' # 2504
unzip -l lucene-analysis-common-9.11.1.jar '*.class' | grep -c '\.class' # 631
unzip -l lucene-queryparser-9.11.1.jar '*.class' | grep -c '\.class' # 250
unzip -l lucene-core-9.11.1.jar 'org/apache/lucene/search/*.class' \
| grep -o 'search/[A-Za-z0-9_]*\.class' | sort -u | wc -l # 190
unzip -l lucene-analysis-common-9.11.1.jar '*.class' \
| grep -o '[A-Za-z0-9_]*Filter\.class' | sort -u | wc -l # 122 token filters
unzip -l lucene-analysis-common-9.11.1.jar '*.class' \…. A symbol with no case is untested, never a match.
| Upstream symbol | Go symbol | Status | Cases | Note |
|---|---|---|---|---|
| StandardTokenizer (UAX#29) | unexported tokenize | differs | an-lower-underscore, an-lower-decimal, an-lower-apostrophe, an-lower-email, an-lower-cjk, an-lower-hyphen, an-lower-slash, an-lower-symbols, an-lower-digits, an-lower-punct-only, an-lower-whitespace, an-lower-empty | the port splits on every non-letter/digit rune; UAX#29 keeps foo_bar, 3.14, don't, example.com together and splits CJK per ideograph |
| LowerCaseFilter | built into Analyzer | match | an-lower-basic, an-lower-mixedcase, an-lower-diacritics | no diacritic folding on either side |
| StopFilter | lucene.WithStopWords | match | an-stop-sentence, an-stop-all, an-stop-case, an-stop-not, an-stop-corpus-d09 | membership behaviour agrees; the *positional* consequence does not (below) |
| PositionIncrementAttribute | lucene.Token.Position | differs | an-pos-lower (match), an-pos-stop-gap, an-pos-stop-leading, an-pos-standard | StopFilter leaves a positional hole (0:trees 2:graphs 4:hash); the port renumbers densely (0 1 2). This is the root cause of the phrase-query divergences |
| PorterStemFilter / PorterStemmer | unexported stem | differs | all 14 an-porter-* (1 matches) | the port is **not** Porter. See the table below |
| EnglishAnalyzer | lucene.NewStandardAnalyzer | differs | an-english-basic, an-english-possessive | |
| EnglishPossessiveFilter | — | missing | an-english-possessive | lucene's → upstream lucen; the port emits lucen, s |
| EnglishAnalyzer.ENGLISH_STOP_WORDS_SET | lucene.DefaultStopWords | match | an-stopwords-default | the port copies Lucene's classic 33-word list verbatim |
| Analyzer.tokenStream | Analyzer.Analyze | match | the whole analyzer group | protocol-level equivalence: same call shape, same output shape |
| Analyzer (query-term path) | Analyzer.AnalyzeTerm | match | q-term-uppercase, ix-docfreq-uppercase | |
| NGramTokenizer | lucene.NGrams | differs | ng-3, ng-1, ng-exact-len, ng-too-long, ng-empty, ng-unicode, ng-space (match), ng-zero, ng-negative | upstream rejects minGram < 1; the port returns an empty slice |
| EdgeNGramTokenizer | lucene.EdgeNGrams | differs | eng-1-3, eng-2-2, eng-clamp-max, eng-empty, eng-unicode (match), eng-min-zero, eng-max-lt-min | upstream throws on minGram < 1 and on maxGram < minGram; the port clamps silently |
| ShingleFilter | lucene.Shingles | differs | sh-2, sh-3, sh-exact, sh-too-few, sh-empty (match), sh-one, sh-zero | upstream requires shingle size ≥ 2 and throws; the port defaults n<1 to 2 and accepts n=1 |
| KStemFilter, EnglishMinimalStemFilter, SnowballFilter, ASCIIFoldingFilter, SynonymGraphFilter, WordDelimiterGraphFilter, CJKBigramFilter, ClassicTokenizer, KeywordTokenizer, PatternTokenizer, PathHierarchyTokenizer, HTMLStripCharFilter, … (≈122 token filters, 16 tokenizers, 50 analyzers) | — | missing | — | the port has exactly one analysis pipeline with two on/off switches |
| TermQuery | lucene.NewTermQuery | match | 8 q-term-* | including missing terms, stop words, unknown fields, tf>1, ranked order |
| TermInSetQuery | lucene.NewTermsQuery | match | 4 q-terms-* | empty set matches nothing on both sides |
| PhraseQuery | lucene.NewPhraseQuery | differs | 7 q-phrase-* (6 match) | q-phrase-stopword-hole: upstream needs slop across a StopFilter hole and finds 0; the port's dense positions find 1 |
| PhraseQuery slop | — | missing | p-phrase-slop | no setSlop equivalent |
| MultiPhraseQuery, NGramPhraseQuery, SpanNearQuery etc. | — | missing | — | |
| BooleanQuery + BooleanClause.Occur.MUST/SHOULD/MUST_NOT | lucene.NewBooleanQuery, Must/Should/MustNot | match | 10 q-bool-* | nesting, cross-field, purely-negative, unsatisfiable, empty all agree |
| BooleanClause.Occur.FILTER | — | missing | — | the port has no non-scoring filter clause |
| BooleanQuery.setMinimumNumberShouldMatch | — | missing | — | |
| PrefixQuery | lucene.NewPrefixQuery | differs | 6 q-prefix-* (3 match) | three separate divergences: NET (port lowercases, upstream does not), "" (upstream matches all 12, port matches 0), and ranked order (d03,d04 vs d04,d03) because upstream rewrites to a blended constant score while the port sums BM25 per matching term |
| WildcardQuery | lucene.NewWildcardQuery | match | 5 q-wildcard-* | |
| RegexpQuery | lucene.NewRegexpQuery | match | 6 q-regexp-* | Lucene's own RegExp syntax vs Go RE2; anchoring, classes, alternation and the invalid-pattern rejection all agree over this corpus |
| FuzzyQuery | lucene.NewFuzzyQuery | differs | 6 q-fuzzy-* (4 match) | the port uses **plain** Levenshtein, upstream **Damerau**-Levenshtein: netwrok~1 finds 2 docs upstream, 0 in the port. The port also accepts maxEdits=3 where upstream throws |
| TermRangeQuery | lucene.NewRangeQuery | match | 7 q-range-* | inclusive/exclusive/half-open/unbounded/inverted all agree ("" ≡ null for unbounded) |
| PointRangeQuery, PointInSetQuery, IndexSortSortedNumericDocValuesRangeQuery | — | missing | — | the port has no typed/numeric point fields at all |
| BoostQuery | lucene.NewBoostQuery | match | 4 q-boost-* | including a boost large enough to reorder, and boost 0 — where the port rewrites 0→1 but the resulting *order* still agrees |
| ConstantScoreQuery | lucene.NewConstantScoreQuery | match | 4 q-const-* | |
| DisjunctionMaxQuery | lucene.NewDisjunctionMaxQuery | match | 5 q-dismax-* | tieBreaker 0 / 0.5 / 1, single and empty disjunct lists |
| MatchAllDocsQuery | lucene.MatchAllQuery | match | q-matchall, q-matchall-topn | |
| MatchNoDocsQuery | — | missing | — | |
| SynonymQuery, BlendedTermQuery, IndexOrDocValuesQuery, FieldExistsQuery, KnnFloatVectorQuery, KnnByteVectorQuery, FloatVectorSimilarityQuery, IndriQuery, AutomatonQuery, MultiTermQuery.RewriteMethod, Sort/SortField, QueryRescorer, LRUQueryCache, Collector/CollectorManager, Explanation (~190 classes in o.a.l.search alone) | — | missing | — | |
| IndexSearcher.search(Query,int) | Index.Search | match | q-topn-one, q-matchall-topn | topN truncation and total-count semantics agree |
| IndexSearcher.count | Result.Total | match | every search case | |
| BM25Similarity | unexported bm25 | untested | — | numeric scores are deliberately not compared**; only the order they induce |
| Similarity, ClassicSimilarity, LMDirichletSimilarity, DFRSimilarity, … | — | missing | — | the port's similarity is fixed and unconfigurable |
| bare term, two terms, default OR | supported | match | p-term, p-two-terms, p-ranked-two-terms, p-ranked-field | |
| field:term, two qualified clauses | supported | match | p-field, p-field-two | |
| +must, -mustNot | supported | match | p-must-both, p-must-not, p-only-negative, p-plus-minus | |
| "phrase", field:"phrase", +"phrase" -term | supported | match | p-phrase, p-phrase-field, p-phrase-required | |
| "the network" (stop word inside a phrase) | kept literally | differs | p-phrase-stopword | upstream drops the stop word and matches 2 docs; the port keeps the, so the phrase matches nothing |
| (grouping), nested with +/- | supported | match | p-group, p-group-nested | |
| term* prefix, field:term* | supported | match | p-prefix, p-prefix-field | |
| [a TO c], {a TO b}, field:[a TO d], [t TO *] | supported | match | p-range-inclusive, p-range-exclusive, p-range-field, p-range-star | |
| [A TO C] (uppercase bounds) | lowercased | differs | p-range-uppercase-bounds | upstream does not analyse range bounds (0 hits); the port lowercases them (2 hits) |
| *:* | supported | match | p-matchall | |
| empty / blank input | MatchAllQuery | differs | p-empty, p-blank | upstream raises ParseException; the port silently returns *every* document |
| AND / && | literal term | differs | p-and-keyword, p-ampersands, p-and-not | search AND library: upstream 1 doc, the port 2. The port lexes AND as an ordinary term and ORs three clauses |
| OR | literal term | match | p-or-keyword | same result set only because OR is already the default operator |
| NOT | literal term | differs | p-not-keyword, p-and-not | search NOT library: upstream 1 doc, the port 2 |
| ~ (fuzzy, term~, term~1) | literal term character | differs | p-fuzzy-n, p-fuzzy-default | netwrk~1: upstream 2 docs, the port searches for the literal term netwrk~1 and finds 0 |
| ~n (phrase slop) | literal | differs | p-phrase-slop (matches only because both find 0) | no slop support |
| ^ (boost) | literal term character | differs | p-boost, p-boost-clause | search^3: upstream 2 docs, the port 0 — it looks for the term search^3 |
| ? (single-char wildcard) | literal term character | differs | p-wildcard-question, p-wildcard-mid | n?twork: upstream 2 docs, the port 0 |
| leading wildcard *work | star dropped | differs | p-wildcard-leading | upstream rejects it with ParseException; the port silently searches for work |
| /regexp/ | no syntax | differs | p-regexp | /colou?r/: upstream 1 doc, the port 0 |
| \: escapes | no escape mechanism | match | p-escaped-colon | both find 0 over this corpus |
| :search (leading colon) | silently skipped | differs | p-leading-colon | upstream ParseException; the port returns 2 docs |
| (search, search), "neural, [a c] | rejected | match | p-unbalanced-paren, p-extra-paren, p-unterminated-quote, p-bad-range | both sides fail — the port's structural error detection is sound |
| MultiFieldQueryParser, ComplexPhraseQueryParser, SimpleQueryParser, StandardQueryParser (flexible), surround, xml parsers (~250 classes) | — | missing | — | |
| IndexReader.numDocs | Index.NumDocs | match | ix-numdocs-stop, ix-numdocs-standard | |
| FieldInfos | Index.Fields | match | ix-fields-stop | both sorted |
| Terms / TermsEnum | Index.Terms | differs | ix-terms-text-stop, ix-terms-title-stop (match), ix-terms-text-standard, ix-terms-unknown-field (match) | the unstemmed dictionaries are **identical** (55 terms) — the corpus was chosen so tokenizer differences cannot leak in; the stemmed one diverges on 11 of 53 positions (22 distinct terms differ between the two dictionaries) |
| Terms.size | Index.TermCount | match | ix-termcount-text, ix-termcount-title, ix-termcount-unknown | |
| IndexReader.docFreq | Index.DocFreq | match | 8 ix-docfreq-* | including uppercase, stop word, missing term, unknown field, and both analyzers |
| IndexReader.totalTermFreq | Index.TotalTermFreq | match | ix-ttf-lists, ix-ttf-search, ix-ttf-missing | |
| IndexWriter.addDocument/updateDocument | Index.Add | match | implied by every case (the corpus is indexed through it) | the port's Add is add-or-replace |
| IndexWriter.deleteDocuments | Index.Delete | untested | — | no upstream-comparable case: the corpus is fixed |
| IndexReader.document / StoredFields | — | missing | — | the port stores no field values; it returns ids only |
| IndexWriter.commit/flush/forceMerge/rollback, SegmentInfos, DirectoryReader.openIfChanged, SearcherManager, NRT | — | missing | — | |
| WildcardQuery.getAutomaton + CharacterRunAutomaton | lucene.WildcardMatch | differs | 14 wc-* (12 match) | *, ?, multi-star, backtracking, brackets-as-literals and Unicode all agree. \* escapes are honoured upstream and unsupported by the port; an empty pattern compiles to the *empty* automaton upstream (matches nothing) but matches "" in the port |
| LevenshteinAutomata | lucene.LevenshteinDistance | differs | 9 lev-* (8 match) | agrees on distance semantics including code-point granularity; upstream caps at 2 edits and throws above it, the port has no cap |
| JaroWinklerDistance (lucene/suggest) | lucene.JaroWinklerSimilarity | untested | — | the suggest module is not among the pinned artifacts |
| LevenshteinDistance.getDistance (suggest) | lucene.LevenshteinSimilarity | untested | — | as above |
| NGramDistance (suggest) | lucene.NGramSimilarity | untested | — | as above |
| DoubleMetaphoneFilter / phonetic module | lucene.Soundex | untested | — | analysis-phonetic is not pinned; Lucene has no plain-Soundex public function |
| — | lucene.DamerauLevenshteinDistance | extra | — | exported but unused by FuzzyQuery, which is why q-fuzzy-transposition-1 diverges |
| — | lucene.JaroSimilarity | extra | — | |
| Highlighter (lucene-highlighter) | lucene.Highlighter, NewHighlighter, Highlight | untested | — | module not pinned; the port's version is a different design (word-level marker wrapping) |
| MoreLikeThis (lucene-queries) | Index.MoreLikeThis | untested | — | module not pinned |
| SpellChecker (lucene-suggest) | Index.SpellCheck | untested | — | module not pinned |
| Suggesters (AnalyzingSuggester, FuzzySuggester, …) | Index.Suggest | untested | — | module not pinned |
| Faceting (lucene-facet: FacetsCollector, SortedSetDocValuesFacetCounts) | Index.FacetCounts, FacetResult | untested | — | module not pinned; the port's version is term-counting, not a taxonomy |
| — | lucene.Error, Occur, Clause, Hit, Result, Document, Token, AnalyzerOption | extra | — | Go-idiomatic plumbing types with no upstream counterpart |
Every case the harness streamed to both runners, with the exact upstream symbol and Go symbol it exercised. A deliberate, documented difference is a deviation and is counted apart from a mismatch.
| Case | Group | Upstream symbol | Go symbol | Status | Note |
|---|---|---|---|---|---|
| an-lower-basic | analyzer | StandardTokenizer+LowerCaseFilter | lucene.NewAnalyzer(WithStemming(false)).Analyze | match | plain ascii words |
| an-lower-mixedcase | analyzer | LowerCaseFilter | Analyzer.Analyze | match | |
| an-lower-empty | analyzer | Analyzer.tokenStream | Analyzer.Analyze | match | empty input yields no tokens |
| an-lower-punct-only | analyzer | StandardTokenizer | Analyzer.Analyze | match | |
| an-lower-whitespace | analyzer | StandardTokenizer | Analyzer.Analyze | match | |
| an-lower-underscore | analyzer | StandardTokenizer | lucene.tokenize | mismatch | UAX#29 keeps foo_bar together; the port splits on underscore |
| an-lower-decimal | analyzer | StandardTokenizer | lucene.tokenize | mismatch | UAX#29 keeps 3.14 as one numeric token |
| an-lower-apostrophe | analyzer | StandardTokenizer | lucene.tokenize | mismatch | |
| an-lower-hyphen | analyzer | StandardTokenizer | lucene.tokenize | match | |
| an-lower-slash | analyzer | StandardTokenizer | lucene.tokenize | match | |
| an-lower-symbols | analyzer | StandardTokenizer | lucene.tokenize | match | |
| an-lower-email | analyzer | StandardTokenizer | lucene.tokenize | mismatch | |
| an-lower-diacritics | analyzer | LowerCaseFilter | Analyzer.Analyze | match | no folding on either side |
| an-lower-cjk | analyzer | StandardTokenizer | lucene.tokenize | mismatch | UAX#29 emits one token per CJK ideograph |
| an-lower-digits | analyzer | StandardTokenizer | lucene.tokenize | match | |
| an-stop-sentence | analyzer | StopFilter | lucene.WithStopWords | match | |
| an-stop-all | analyzer | StopFilter | lucene.WithStopWords | match | every token is a stop word |
| an-stop-case | analyzer | StopFilter | lucene.WithStopWords | match | stop words match after lowercasing |
| an-stop-not | analyzer | StopFilter | lucene.WithStopWords | match | |
| an-stop-corpus-d09 | analyzer | StopFilter | lucene.WithStopWords | match | |
| an-porter-runners | analyzer | PorterStemFilter | lucene.stem | mismatch | known port divergence: Runners |
| an-porter-documents | analyzer | PorterStemFilter | lucene.stem | mismatch | |
| an-porter-plurals | analyzer | PorterStemFilter | lucene.stem | match | Porter step 1a |
| an-porter-ed-ing | analyzer | PorterStemFilter | lucene.stem | mismatch | Porter step 1b |
| an-porter-fixup | analyzer | PorterStemFilter | lucene.stem | mismatch | Porter step 1b cleanup |
| an-porter-y | analyzer | PorterStemFilter | lucene.stem | mismatch | Porter step 1c (y -> i) is absent from the port |
| an-porter-step2 | analyzer | PorterStemFilter | lucene.stripDerivational | mismatch | |
| an-porter-step3 | analyzer | PorterStemFilter | lucene.stripDerivational | mismatch | |
| an-porter-step4 | analyzer | PorterStemFilter | lucene.stripDerivational | mismatch | |
| an-porter-step5 | analyzer | PorterStemFilter | lucene.stem | mismatch | Porter step 5a/5b |
| an-porter-short | analyzer | PorterStemFilter | lucene.stem | match | port leaves words of four runes or fewer untouched |
| an-porter-generalization | analyzer | PorterStemFilter | lucene.stem | mismatch | |
| an-porter-er-or | analyzer | PorterStemFilter | lucene.stem | mismatch | port strips -er/-or unconditionally at m>0 |
| an-porter-ly-ful | analyzer | PorterStemFilter | lucene.stem | mismatch | |
| an-standard-corpus | analyzer | StandardTokenizer+LowerCaseFilter+StopFilter+PorterStemFilter | lucene.NewStandardAnalyzer | mismatch | |
| an-standard-runners | analyzer | StandardTokenizer+LowerCaseFilter+StopFilter+PorterStemFilter | lucene.NewStandardAnalyzer | mismatch | |
| an-standard-stopword-stem | analyzer | StandardTokenizer+LowerCaseFilter+StopFilter+PorterStemFilter | lucene.NewStandardAnalyzer | match | stop words are dropped before stemming on both sides |
| an-english-basic | analyzer | EnglishAnalyzer | lucene.NewStandardAnalyzer | mismatch | port's nearest equivalent to EnglishAnalyzer |
| an-english-possessive | analyzer | EnglishAnalyzer | lucene.NewStandardAnalyzer | mismatch | EnglishPossessiveFilter has no counterpart in the port |
| an-pos-lower | analyzer | PositionIncrementAttribute | lucene.Token.Position | match | |
| an-pos-stop-gap | analyzer | PositionIncrementAttribute | lucene.Token.Position | mismatch | StopFilter leaves a positional hole; the port renumbers densely |
| an-pos-stop-leading | analyzer | PositionIncrementAttribute | lucene.Token.Position | mismatch | |
| an-pos-standard | analyzer | PositionIncrementAttribute | lucene.Token.Position | mismatch | |
| an-stopwords-default | analyzer | EnglishAnalyzer.getDefaultStopSet | lucene.DefaultStopWords | match | sorted; the port copies Lucene's classic 33-word English list |
| ix-numdocs-stop | index | IndexReader.numDocs | lucene.Index.NumDocs | match | |
| ix-numdocs-standard | index | IndexReader.numDocs | lucene.Index.NumDocs | match | |
| ix-fields-stop | index | FieldInfos | lucene.Index.Fields | match | |
| ix-terms-text-stop | index | Terms/TermsEnum | lucene.Index.Terms | match | the whole term dictionary, sorted; proves both sides indexed the same tokens |
| ix-terms-title-stop | index | Terms/TermsEnum | lucene.Index.Terms | match | |
| ix-terms-text-standard | index | Terms/TermsEnum | lucene.Index.Terms | mismatch | stemmed dictionary; divergences here are stemmer divergences |
| ix-terms-unknown-field | index | LeafReader.terms | lucene.Index.Terms | match | |
| ix-termcount-text | index | Terms.size | lucene.Index.TermCount | match | |
| ix-termcount-title | index | Terms.size | lucene.Index.TermCount | match | |
| ix-termcount-unknown | index | Terms.size | lucene.Index.TermCount | match | |
| ix-docfreq-search | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ix-docfreq-lists | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ix-docfreq-uppercase | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ix-docfreq-stopword | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ix-docfreq-missing | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ix-docfreq-unknown-field | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ix-ttf-lists | index | IndexReader.totalTermFreq | lucene.Index.TotalTermFreq | match | two occurrences in one document |
| ix-ttf-search | index | IndexReader.totalTermFreq | lucene.Index.TotalTermFreq | match | |
| ix-ttf-missing | index | IndexReader.totalTermFreq | lucene.Index.TotalTermFreq | match | |
| ix-docfreq-std-documents | index | IndexReader.docFreq | lucene.Index.DocFreq | match | term is analysed with the stemming analyzer on both sides |
| ix-docfreq-std-runners | index | IndexReader.docFreq | lucene.Index.DocFreq | match | |
| ng-3 | ngram | NGramTokenizer | lucene.NGrams | match | |
| ng-1 | ngram | NGramTokenizer | lucene.NGrams | match | |
| ng-exact-len | ngram | NGramTokenizer | lucene.NGrams | match | |
| ng-too-long | ngram | NGramTokenizer | lucene.NGrams | match | n larger than the input |
| ng-empty | ngram | NGramTokenizer | lucene.NGrams | match | |
| ng-zero | ngram | NGramTokenizer | lucene.NGrams | mismatch | Lucene rejects minGram < 1 |
| ng-negative | ngram | NGramTokenizer | lucene.NGrams | mismatch | Lucene rejects a negative gram size |
| ng-unicode | ngram | NGramTokenizer | lucene.NGrams | match | code-point granularity |
| ng-space | ngram | NGramTokenizer | lucene.NGrams | match | NGramTokenizer does not treat space specially by default |
| eng-1-3 | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | match | |
| eng-2-2 | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | match | |
| eng-clamp-max | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | match | maxGram beyond the input length |
| eng-min-zero | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | mismatch | Lucene rejects minGram < 1 |
| eng-max-lt-min | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | mismatch | Lucene rejects maxGram < minGram |
| eng-empty | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | match | |
| eng-unicode | ngram | EdgeNGramTokenizer | lucene.EdgeNGrams | match | |
| sh-2 | ngram | ShingleFilter | lucene.Shingles | match | |
| sh-3 | ngram | ShingleFilter | lucene.Shingles | match | |
| sh-exact | ngram | ShingleFilter | lucene.Shingles | match | |
| sh-too-few | ngram | ShingleFilter | lucene.Shingles | match | fewer tokens than the shingle size |
| sh-one | ngram | ShingleFilter | lucene.Shingles | mismatch | Lucene requires minShingleSize >= 2 |
| sh-empty | ngram | ShingleFilter | lucene.Shingles | match | |
| sh-zero | ngram | ShingleFilter | lucene.Shingles | mismatch | the port silently defaults n<1 to 2 |
| p-term | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-two-terms | parser | QueryParser.parse | lucene.Parser.Parse | match | default operator is OR on both sides |
| p-field | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-field-two | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-must-both | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-must-not | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-only-negative | parser | QueryParser.parse | lucene.Parser.Parse | match | purely negative query |
| p-plus-minus | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-phrase | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-phrase-field | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-phrase-required | parser | QueryParser.parse | lucene.Parser.Parse | match | |
| p-phrase-stopword | parser | QueryParser.parse | lucene.Parser.Parse | mismatch | upstream drops the stop word from the phrase; the port keeps it and finds nothing |