Как индексировать коды стран запроса с помощью lucene?

Я создаю индекс lucene для названий городов и кодов стран (в зависимости друг от друга). Я хочу, чтобы коды стран были доступны для поиска в нижнем регистре и точно соответствовали.

Сначала я пытаюсь запросить один код страны и найти все проиндексированные элементы, соответствующие этому коду. По моему результат всегда пустой.

//prepare
VERSION = Version.LUCENE_4_9;
IndexWriterConfig config = new IndexWriterConfig(VERSION, new SimpleAnalyzer());

//index
Document doc = new Document();
doc.add(new StringField("countryCode", countryCode, Field.Store.YES));
writer.addDocument(doc);

//lookup
Query query = new QueryParser(VERSION, "countryCode", new SimpleAnalyzer()).parse(countryCode);

Результат: когда я запрашиваю коды стран, такие как «IT», «DE», «EN» и т. д., результат всегда пуст. Почему? Является ли SimpleAnalyzer двухбуквенным кодом страны?


person membersound    schedule 01.08.2014    source источник


Ответы (2)


Я немного смущен здесь. Я предполагаю, что ваш индексатор инициализирован в какой-то части вашего кода, которая не указана, но вы стесняетесь, не передаете ли вы Version в SimpleAnalyzer? Нет конструктора no arg для SimpleAnalyzer, во всяком случае, начиная с 3.X.

Это единственная реальная проблема, которую я вижу. Вот рабочий пример с использованием вашего кода:

private static Version VERSION;

public static void main(String[] args) throws IOException, ParseException {
    //prepare
    VERSION = Version.LUCENE_4_9;
    Directory dir = new RAMDirectory();
    IndexWriterConfig config = new IndexWriterConfig(VERSION, new SimpleAnalyzer(VERSION));
    IndexWriter writer = new IndexWriter(dir, config);

    String countryCode = "DE";

    //index
    Document doc = new Document();
    doc.add(new TextField("countryCode", countryCode, Field.Store.YES));
    writer.addDocument(doc);
    writer.close();

    IndexSearcher search = new IndexSearcher(DirectoryReader.open(dir));
    //lookup
    Query query = new QueryParser(VERSION, "countryCode", new SimpleAnalyzer(VERSION)).parse(countryCode);

    TopDocs docs = search.search(query, 1);
    System.out.println(docs.totalHits);
}
person femtoRgon    schedule 02.08.2014
comment
Я обнаружил проблему: я использовал StringField вместо TextField, потому что в документах говорится: Поле, которое индексируется, но не токенизируется: все значение String индексируется как один токен. Например, это может быть использовано для поля «страна» или «идентификатор». Вы знаете, почему это не работает? Это работает при использовании TextField, как вы предложили. + - person membersound; 04.08.2014
comment
Да, это редактирование объясняет это. StringField не анализируется, индексированное представление по-прежнему в верхнем регистре. Однако ваш запрос все еще анализируется, поэтому он будет переведен в нижний регистр SimpleAnalyzer. - person femtoRgon; 04.08.2014

Для StringField можно использовать TermQuery вместо QueryParser.

Directory dir = new RAMDirectory();
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_9, new SimpleAnalyzer(Version.LUCENE_4_9));
IndexWriter writer = new IndexWriter(dir, config);

String countryCode = "DE";

// index
Document doc = new Document();
doc.add(new StringField("countryCode", countryCode, Store.YES));
writer.addDocument(doc);
writer.close();

IndexSearcher search = new IndexSearcher(DirectoryReader.open(dir));
//lookup
Query query = new TermQuery(new Term("countryCode", countryCode));

TopDocs docs = search.search(query, 1);
System.out.println(docs.totalHits);
person serem    schedule 07.08.2014