Le programme suivant:Lucene QueryParser comportement incohérent
import java.util.Arrays;
import java.util.List;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.util.Version;
public class LuceneTest {
static final List<Character> SPECIAL_CHARS =
Arrays.asList('\\', '+', '-', '!', '(', ')', ':', '^', '[', ']', '"', '{', '}', '~', '*', '?', '|', '&');
public static void main(String[] args) throws ParseException {
QueryParser query =
new QueryParser(Version.LUCENE_31, "", new StandardAnalyzer(Version.LUCENE_31));
for (char c : SPECIAL_CHARS) {
System.out.println(c + " -> " + query.parse("__catch_all:foo\\" + c + "bar").toString());
}
}
}
donne cette sortie:
\ -> __catch_all:foo __catch_all:bar
+ -> __catch_all:foo __catch_all:bar
- -> __catch_all:foo __catch_all:bar
! -> __catch_all:foo __catch_all:bar
(-> __catch_all:foo __catch_all:bar
) -> __catch_all:foo __catch_all:bar
: -> __catch_all:foo:bar
^ -> __catch_all:foo __catch_all:bar
[ -> __catch_all:foo __catch_all:bar
] -> __catch_all:foo __catch_all:bar
" -> __catch_all:foo __catch_all:bar
{ -> __catch_all:foo __catch_all:bar
} -> __catch_all:foo __catch_all:bar
~ -> __catch_all:foo __catch_all:bar
* -> __catch_all:foo __catch_all:bar
? -> __catch_all:foo __catch_all:bar
| -> __catch_all:foo __catch_all:bar
& -> __catch_all:foo __catch_all:bar
Notez la contradiction apparente avec: et notez aussi que je suis échapper au caractère spécial (faire exactement même chose que QueryParser.escape). Je m'attends à ce que StandardAnalyzer supprime la ponctuation spéciale des termes de la requête, et cela dans presque tous les cas.
La raison pour laquelle cela semble particulièrement contradictoire est que la rédaction d'un document avec un StandardAnalyzer et un texte sur le terrain de « foo: bar » va me donner un deux champs terme, foo et bar! Un second cycle d'échappement donne le résultat correct, c'est-à-dire, "foo \\: bar"; mais pourquoi est-ce nécessaire seulement pour les deux-points? Pourquoi devrais-je besoin de faire QueryParser.escape (QueryParser.escape (mystring)) pour éviter ce comportement?
C'est beaucoup d'informations, merci. Du côté de * write *, il semble que StandardAnalyzer tokenise la chaîne en tant que "foo bar", ce qui semble incohérent. – HenryR
Qu'est-ce qui vous fait penser ainsi? Pouvez-vous fournir un morceau de code qui montre ce problème? – jpountz