Lucene: исключение — синтаксический анализатор запросов обнаружил ‹EOF› после некоторого слова

Я работаю над проблемой классификации, чтобы классифицировать отзывы о продуктах как положительные, отрицательные или нейтральные в соответствии с данными обучения с использованием Lucene API.

Я использую объекты ArrayList of Review — «reviewList», в котором хранятся атрибуты для каждого обзора при сканировании веб-страниц.

Атрибуты обзора, которые включают «полярность» и «содержание обзора», затем индексируются с помощью индексатора. После этого на основе объектов индексов мне нужно классифицировать оставшиеся объекты обзора. Но при этом есть объект обзора, для которого синтаксический анализатор запросов встречает символ EOF в «содержимом обзора» и, следовательно, завершает работу.

Строка, вызывающая ошибку, была соответствующим образом прокомментирована -

    IndexReader reader = IndexReader.open(FSDirectory.open(new File("index")));
    IndexSearcher searcher = new IndexSearcher(reader);
    Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_31);
    QueryParser parser = new QueryParser(Version.LUCENE_31, "Review", analyzer);

    int length = Crawler.reviewList.size();
    for (int i = 200; i < length; i++) {
        String true_class;
        double r_stars = Crawler.reviewList.get(i).getStars();

        if (r_stars < 2.0) {
            true_class = "-1";
        } else if (r_stars > 3.0) {
            true_class = "1";
        } else {
            true_class = "0";
        }

        String[] reviewTokens = Crawler.reviewList.get(i).getReview().split(" ");
        String parsedReview = "";

        int j;

        for (j = 0; j < reviewTokens.length; j++) {
            if (reviewTokens[j] != null) {
                if (!((reviewTokens[j].contains("-")) || (reviewTokens[j].contains("!")))) {
                    parsedReview += reviewTokens[j] + " ";
                }
            } else {
                break;
            }
        }

        Query query = parser.parse(parsedReview); // CAUSING ERROR!!

        TopScoreDocCollector results = TopScoreDocCollector.create(5, true);
        searcher.search(query, results);
        ScoreDoc[] hits = results.topDocs().scoreDocs;

Я проанализировал текст вручную, чтобы удалить символы, вызывающие ошибку, кроме проверки того, является ли следующая строка нулевой... но ошибка сохраняется.

Это трассировка стека ошибок -

Exception in thread "main" org.apache.lucene.queryParser.ParseException: Cannot parse 'I made the choice ... be all "thumbs ': Lexical error at line 1, column 938.  Encountered: <EOF> after : "\"thumbs "
at org.apache.lucene.queryParser.QueryParser.parse(QueryParser.java:216)
at Sentiment_Analysis.Classification.classify(Classification.java:58)
at Sentiment_Analysis.Main.main(Main.java:17)
Caused by: org.apache.lucene.queryParser.TokenMgrError: Lexical error at line 1, column 938.  Encountered: <EOF> after : "\"thumbs "
at org.apache.lucene.queryParser.QueryParserTokenManager.getNextToken(QueryParserTokenManager.java:1229)
at org.apache.lucene.queryParser.QueryParser.jj_scan_token(QueryParser.java:1709)
at org.apache.lucene.queryParser.QueryParser.jj_3R_2(QueryParser.java:1598)
at org.apache.lucene.queryParser.QueryParser.jj_3_1(QueryParser.java:1605)
at org.apache.lucene.queryParser.QueryParser.jj_2_1(QueryParser.java:1585)
at org.apache.lucene.queryParser.QueryParser.Clause(QueryParser.java:1280)
at org.apache.lucene.queryParser.QueryParser.Query(QueryParser.java:1266)
at org.apache.lucene.queryParser.QueryParser.Clause(QueryParser.java:1313)
at org.apache.lucene.queryParser.QueryParser.Query(QueryParser.java:1266)
at org.apache.lucene.queryParser.QueryParser.TopLevelQuery(QueryParser.java:1226)
at org.apache.lucene.queryParser.QueryParser.parse(QueryParser.java:206)
... 2 more
Java Result: 1

Пожалуйста, помогите мне решить эту проблему ... уже несколько часов бьюсь об это головой!


person Reema    schedule 21.04.2012    source источник


Ответы (2)


Вы должны избегать двойных кавычек и других специальных символов через

Query query = parser.parse(QueryParser.escape(parsedReview));

Как QueryParser.escape предложил Javadoc,

Возвращает строку, в которой те символы, которые QueryParser ожидает экранировать, экранируются предшествующим символом '\'.

person Pau Kiat Wee    schedule 21.04.2012
comment
Благодаря тонну! Это было в точку.. :D - person Reema; 21.04.2012
comment
Для тех, кто использует более поздние выпуски (для меня Lucene 4.6), функция escape была перемещена в класс QueryParserUtil. - person Chunliang Lyu; 24.01.2014
comment
Я хочу сделать это, используя библиотеку solr вместо библиотеки lucene, есть идеи? - person Divyang Shah; 02.04.2015
comment
@ChunliangLyu в Lucene 4.10.4 escape() все еще находится в QueryParser (унаследованном от QueryParserBase), но, как вы упомянули, также есть один в QueryParserUtil. -Интересно, какая разница..? - person Superole; 04.12.2015
comment
@Superole Да, вы правы, QueryParser наследует метод от QueryParserBase. Я проверил реализации QueryParserBase и QueryParserUtil в текущей версии, оказывается, они точно такие же. Таким образом, никакой разницы в функциональности, возможно, небольшая разница в производительности. - person Chunliang Lyu; 05.12.2015
comment
Считается ли уязвимостью, если пользователи могут вводить и анализировать произвольные значения, которые не экранированы? - person Aaron Esau; 22.10.2017

Я признаю эту проблему.

Объявление GROUP BY перед объявлением WHERE отлично работает в Teradata, но выдает ошибку при синтаксическом анализе.

Чтобы исправить это, переместите объявление GROUP BY после объявления WHERE.

person Rishabh Sharma    schedule 05.06.2017