Нужен совет по оптимизации запросов Lucene

Я работаю над приложением поиска работы через Интернет, используя Lucene.User. На моем сайте можно искать вакансии, которые находятся в радиусе 100 миль, скажем, от "Бостона, Массачусетса" или любого другого места. Кроме того, мне нужно показать результаты поиска, отсортированные по "релевантности"(т. Е. Оценка, возвращаемая lucene) в порядке убывания.

Я использую сторонний API для извлечения всех городов в заданном радиусе города. Этот API возвращает мне около 864 городов в радиусе 100 миль от "Бостона, Массачусетс".

Я создаю запрос Lucene для города / штата, используя следующую логику, которая является частью моего метода "BuildNearestCitiesQuery". Здесь nearCities - это хеш-таблица, возвращенная вышеуказанным API. Он содержит 864 города с ключом задницы CityName и StateCode в качестве значения. И finalQuery - это объект Lucene BooleanQuery, который содержит другие критерии поиска, введенные пользователем, такие как навыки, ключевые слова и т. Д.

foreach (string city in nearestCities.Keys)

{

    BooleanQuery tempFinalQuery = finalQuery;

    cityStateQuery = new BooleanQuery();    

    queryCity = queryParserCity.Parse(city);

    queryState = queryParserState.Parse(((string[])nearestCities[city])[1]);

    cityStateQuery.Add(queryCity, BooleanClause.Occur.MUST); //must is like an AND

    cityStateQuery.Add(queryState, BooleanClause.Occur.MUST);

} 


nearestCityQuery.Add(cityStateQuery, BooleanClause.Occur.SHOULD); //should is like an OR



finalQuery.Add(nearestCityQuery, BooleanClause.Occur.MUST);

Затем я вводю объект finalQuery в метод поиска Lucene, чтобы получить все задания в радиусе 100 миль.

searcher.Search(finalQuery, collector);

Я обнаружил, что этот метод BuildNearestCitiesQuery выполняется в среднем 29 секунд, что, очевидно, недопустимо по любым стандартам веб-сайта. Я также обнаружил, что операторы, включающие "Parse", выполняются в течение значительного времени по сравнению с другими заявления.

Работа для заданного местоположения является динамическим атрибутом в том смысле, что сегодня в городе может быть 2 работы (отвечающие определенным критериям поиска), но через 3 дня работа по тем же критериям поиска не выполняется. Поэтому я не могу использовать "Кэширование" здесь.

Есть ли способ, которым я могу оптимизировать эту логику или, если уж на то пошло, весь мой подход / алгоритм к поиску всех рабочих мест в радиусе 100 миль с помощью Lucene?

К вашему сведению, вот как выглядит моя индексация в Lucene:

doc.Add(new Field("jobId", job.JobID.ToString().Trim(), Field.Store.YES, Field.Index.UN_TOKENIZED));

doc.Add(new Field("title", job.JobTitle.Trim(), Field.Store.YES, Field.Index.TOKENIZED));

doc.Add(new Field("description", job.JobDescription.Trim(), Field.Store.NO, Field.Index.TOKENIZED));

doc.Add(new Field("city", job.City.Trim(), Field.Store.YES, Field.Index.TOKENIZED , Field.TermVector.YES));

doc.Add(new Field("state", job.StateCode.Trim(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.YES));

doc.Add(new Field("citystate", job.City.Trim() + ", " + job.StateCode.Trim(), Field.Store.YES, Field.Index.UN_TOKENIZED , Field.TermVector.YES));

doc.Add(new Field("datePosted", jobPostedDateTime, Field.Store.YES, Field.Index.UN_TOKENIZED));

doc.Add(new Field("company", job.HiringCoName.Trim(), Field.Store.YES, Field.Index.TOKENIZED));

doc.Add(new Field("jobType", job.JobTypeID.ToString(), Field.Store.NO, Field.Index.UN_TOKENIZED,Field.TermVector.YES));

doc.Add(new Field("sector", job.SectorID.ToString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.YES));

doc.Add(new Field("showAllJobs", "yy", Field.Store.NO, Field.Index.UN_TOKENIZED));

Спасибо большое за чтение! Я был бы очень признателен за вашу помощь в этом.

Janis

6 ответов

Решение

Не совсем уверен, полностью ли я понимаю ваш код, но когда дело доходит до геопространственного поиска, подход фильтра может быть более подходящим. Может быть, эта ссылка может дать вам некоторые идеи - http://sujitpal.blogspot.com/2008/02/spatial-search-with-lucene.html

Возможно, вы можете использовать Filter s для других частей вашего запроса. Если честно, ваш запрос выглядит довольно сложным.

--Hardy

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

Если все время занято в Parse методы, размещение их кода здесь имеет смысл.

Я бы предложил:

  • хранение широты и долготы мест, когда они входят
  • когда пользователь вводит город и расстояние, превратите его в значение широты / долготы и градусы
  • сделать один простой поиск на основе числовых сравнений широт / расстояний

Вы можете увидеть пример того, как это работает в модуле Geo:: Distance Perl. Посмотрите на closest метод в источнике, который реализует этот поиск с помощью простого SQL.

Возможно, я пропустил суть вашего вопроса, но есть ли у вас возможность сохранить широту и долготу для почтовых индексов? Если это вариант, вы можете рассчитать расстояние между двумя координатами, предоставив гораздо более простой показатель оценки.

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

Согласитесь с другими здесь, что это пахнет слишком сильно. Кроме того, текстовый поиск по названиям городов не всегда так надежен. Между географическими названиями часто существует некоторая субъективность (особенно в пределах районов города, которые сами по себе могут быть большими).

Выполнение гео-пространственного запроса - это путь. Не зная остальной части вашей установки, трудно советовать. У вас есть пространственная поддержка, встроенная в Fluent to NHibernate и SQL Server 2008, например. Тогда вы могли бы сделать поиск очень быстро и эффективно. Однако ваша задача - заставить это работать в Lucene.

Возможно, вы могли бы выполнить запрос "первый проход", используя пространственную поддержку в SQL Server, а затем запустить эти результаты через Lucene?

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

Другие вопросы по тегам