首页 文章

需要Lucene查询优化建议

提问于
浏览
3

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

我正在使用第三方API来获取城市给定半径范围内的所有城市 . 这个API让我回到“波士顿,马萨诸塞州”方圆100英里范围内的大约864个城市 .

我正在使用以下逻辑构建城市/州Lucene查询,该逻辑是我的“BuildNearestCitiesQuery”方法的一部分 . 这里的nearestCities是上述API返回的哈希表 . 它包含864个城市,其中CityName为ass键,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));

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

贾尼斯

6 回答

  • 0

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

    也许您也可以将过滤器用于查询的其他部分 . 说实话,你的查询看起来很复杂 .

    --Hardy

  • 3

    除了 tempFinalQuery 未使用和不必要的 Map 查找以获取状态之外,在您发布的代码中似乎没有任何太令人震惊的事情 . 除了格式化......

    如果所有时间都采用 Parse 方法,那么在此处发布代码是有意义的 .

  • 0

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

  • 0

    我认为最好的方法是将最近的城市决定移动到搜索过滤器中 . 我还会重新考虑如何进行现场设置;考虑创建一个具有城市状态的术语,以便简化查询 .

  • 0

    我建议:

    • 存储进入的位置的纬度和经度

    • 当用户输入城市和距离时,将其转换为纬度/经度值和度数

    • 基于数值距离lat / lon比较进行单个简单查找

    您可以在Geo::Distance Perl模块中看到一个如何工作的示例 . 看一下source中的 closest 方法,该方法通过简单的SQL实现此查找 .

  • 0

    在这里与其他人一致认为这闻起来太多了 . 对城市名称进行文本搜索并不总是那么可靠 . 地名之间经常存在一些主观性(特别是城市中可能本身很大的区域) .

    进行地理空间查询是可行的方法 . 不知道你的其他设置,很难建议 . 您可以在Fluent到NHibernate和SQL Server 2008中内置Spatial支持 . 然后,您可以快速有效地搜索 very . 但是,您面临的挑战是如何在Lucene中实现这一目标 .

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

    进行空间查询的另一个主要好处是,您可以轻松地按距离对结果进行排序,这对您的客户来说是一个胜利 .

相关问题