質問

Luceneを使用してWebベースの求人検索アプリケーションで作業しています。私のサイトのユーザーは、「ボストン、マサチューセッツ」から半径100マイル以内にある求人を検索できます。またはその他の場所。 また、検索結果を" relevance"でソートして表示する必要があります(つまり、luceneが返すスコア)。降順で表示する必要があります。

サードパーティのAPIを使用して、特定の都市の半径内のすべての都市を取得します。このAPIは、「ボストン、マサチューセッツ州」の半径100マイル内の約864都市を返します。

「BuildNearestCitiesQuery」の一部である次のロジックを使用して、市/州Luceneクエリを構築しています。方法。 ここで、nearestCitiesは、上記のAPIによって返されるハッシュテーブルです。これには、CityName assキーとStateCodeが値として含まれる864都市が含まれています。 また、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秒かかりますが、これは明らかにWebサイトの標準では受け入れられないことです。他のステートメントと比較して、実行にかなりの時間がかかります。

特定の場所のジョブは、都市が今日2つのジョブ(特定の検索基準を満たす)を持つことができるという意味での動的属性ですが、3日後の同じ検索基準のジョブはゼロです。 "キャッシング"ここに。

このロジックを最適化する方法はありますか?それとも、Luceneを使用して100マイル以内のすべてのジョブを見つけるためのアプローチ/アルゴリズム全体についてですか?

FYI、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));

読んでくれてありがとう!これについてあなたの助けを本当に感謝します。

ジャニス

役に立ちましたか?

解決

私があなたのコードを完全に理解しているかどうかは確かではありませんが、地理空間検索に関しては、フィルター手法がより適切かもしれません。このリンクからアイデアが得られるかもしれません- http:// sujitpal .blogspot.com / 2008/02 / spatial-search-with-lucene.html

クエリの他の部分にも Filter を使用できます。正直なところ、クエリは非常に複雑に見えます。

-ハード

他のヒント

tempFinalQuery が未使用であり、状態を取得するための不必要なマップルックアップを除いて、投稿するコードにあまりにもひどいものはないようです。フォーマットとは別に...

Parse メソッドで常に時間がかかる場合、ここにコードを投稿するのは理にかなっています。

質問のポイントを見逃したかもしれませんが、郵便番号の緯度と経度を保存する可能性はありますか?それがオプションの場合、2つの座標間の距離を計算して、はるかに簡単なスコアリングメトリックを提供できます。

最良のアプローチは、最も近い都市の決定を検索フィルターに移動することだと思います。また、フィールドのセットアップ方法を再検討します。クエリを簡素化するために、市と州を含む1つの用語を作成することを検討してください。

提案:

  • 受信した場所の緯度と経度を保存する
  • ユーザーが都市と距離を入力すると、緯度/経度の値と度数に変換します
  • 緯度/経度の距離の数値比較に基づいて、単一の単純な検索を行います

この仕組みの例は、 Geo :: Distance Perlモジュール。 closest メソッドを見てくださいrel = "nofollow noreferrer ">ソース。これは単純なSQLを介してこのルックアップを実装します。

ここで他の人に、これは臭いが強いことに同意します。また、都市名でテキスト検索を行うことは、必ずしもそれほど信頼できるとは限りません。多くの場合、地名(特に、都市内の大きなエリアである可能性のあるエリア)の間には、若干の主観性があります。

地理空間クエリを実行する方法があります。セットアップの残りの部分がわからない場合、アドバイスするのは困難です。 Fluent to NHibernate、およびたとえばSQL Server 2008に組み込まれたSpatialサポートがあります。その後、非常に迅速かつ効率的に検索できます。ただし、あなたの課題は、これをLucene内で機能させることです。

「最初のパス」を行うことができます; SQL Serverの空間サポートを使用してクエリを実行し、Luceneを介してそれらの結果を実行しますか?

空間クエリを行うことのもう1つの主な利点は、距離で結果を簡単に並べ替えることができることです。これは顧客にとってメリットです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top