3

我正在使用 Lucene 开发基于 Web 的求职应用程序。我网站上的用户可以搜索距离“波士顿,马萨诸塞州”或任何其他位置 100 英里范围内的工作。另外,我需要以降序显示按“相关性”(即lucene返回的分数)排序的搜索结果。

我正在使用第 3 方 API 来获取城市给定半径内的所有城市。这个 API 返回我在“波士顿,MA”半径 100 英里内的大约 864 个城市。

我正在使用以下逻辑构建城市/州 Lucene 查询,这是我的“BuildNearestCitiesQuery”方法的一部分。这里nearestCities 是上述API 返回的哈希表。它包含864 个城市,CityName 作为key,StateCode 作为value。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 的 Search 方法中,以获取 100 英里半径内的所有工作。:

searcher.Search(finalQuery, collector);

我发现这个 BuildNearestCitiesQuery 方法平均需要高达 29 秒的时间来执行,这显然是任何网站标准都不能接受的。我还发现涉及“Parse”的语句与其他语句相比需要相当长的时间来执行陈述。

给定位置的工作是一个动态属性,因为一个城市今天可能有 2 个工作(满足特定搜索条件),但 3 天后相同搜索条件的工作为零。所以,我不能使用任何“缓存”这边。

有什么方法可以优化这个逻辑吗?或者我的整个方法/算法可以使用 Lucene 在 100 英里内找到所有工作?

仅供参考,这是我在 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));

非常感谢您的阅读!非常感谢您对此的帮助。

贾尼斯

4

6 回答 6

3

不太确定我是否完全理解您的代码,但在地理空间搜索方面,过滤方法可能更合适。也许这个链接可以给你一些想法 - http://sujitpal.blogspot.com/2008/02/spatial-search-with-lucene.html

也许您也可以将Filter用于查询的其他部分。老实说,您的查询看起来很复杂。

——哈代

于 2009-06-12T09:01:49.793 回答
0

除了tempFinalQuery未使用和不必要的地图查找来获取状态之外,您发布的代码中似乎没有什么太令人震惊的地方。除了格式...

如果所有时间都花在Parse方法上,那么在这里发布他们的代码是有意义的。

于 2009-01-02T13:58:50.437 回答
0

我可能错过了您的问题的重点,但是您是否可以存储邮政编码的纬度和经度?如果这是一个选项,那么您可以计算两个坐标之间的距离,从而提供更直接的评分指标。

于 2009-06-10T19:38:35.840 回答
0

我相信最好的方法是将最近的城市确定移动到搜索过滤器中。我还会重新考虑您如何进行现场设置;考虑创建一个包含 city+state 的术语,以便简化查询。

于 2009-06-13T04:26:21.380 回答
0

我建议:

  • 存储位置进入时的纬度和经度
  • 当用户输入城市和距离时,将其转换为纬度/经度值和度数
  • 基于数字距离纬度/经度比较进行单一、简单的查找

您可以在Geo::Distance Perl 模块中看到它是如何工作的示例。看一下源码closest中的方法,它通过简单的 SQL 实现了这个查找。

于 2009-06-26T18:21:31.417 回答
0

同意这里的其他人,这闻起来太香了。此外,对城市名称进行文本搜索并不总是那么可靠。地名之间通常存在一些主观性(特别是城市内本身可能很大的区域)。

进行地理空间查询是要走的路。不知道您的其他设置很难提供建议。您确实在 Fluent to NHibernate 和 SQL Server 2008 中内置了空间支持。然后,您可以非常快速有效地进行搜索。但是,您面临的挑战是在 Lucene 中实现这一点。

您可以使用 SQL Server 中的空间支持进行“第一次通过”查询,然后通过 Lucene 运行这些结果吗?

The other major benefit of doing spatial queries is that you can then easily sort your results by distance which is a win for your customers.

于 2009-11-06T13:22:51.267 回答