パーソナライズされた検索を実行するためのDice.comのSOLRプラグイン、および推奨事項(関連性フィードバックプラグインを介して)および概念 /セマンティック検索(監視されていないフィードバックプラグインを介して)。
事前に構築されたJARファイルは./target Targetフォルダーにあります。このプロジェクトには、Sourceからビルドするためにも使用できるMaven POM.xmlファイルが含まれています。
これを必要とする特定のバージョンがある場合は、githubの問題を作成してください。特定のバージョンに手動でコンパイルするには、Mavenを使用してpom.xmlファイルを使用してプラグインをコンパイルし、そのファイルのSolrおよびLuceneライブラリのバージョンを更新し、Mavenを使用してそれらの依存関係を引き込みます。次に、コンピレーションエラーを修正します。
SOLRにプラグインを登録するための公式SOLRガイドラインをご覧ください。これには、基本的に、JARファイルをCore ReloadのクラスおよびJARファイルをチェックするフォルダーの1つにドロップするだけです。
solrconfig.xmlのリクエストハンドラー構成の例を以下に示し、主なパラメーターの概要を説明するコメントを示します。
<requestHandler name="/rf" class="org.dice.solrenhancements.relevancyfeedback.RelevancyFeedbackHandler">
<lst name="defaults">
<str name="omitHeader">true</str>
<str name="wt">json</str>
<str name="indent">true</str>
<!-- Regular query configuration - query parser used when parsing the rf query-->
<str name="defType">lucene</str>
<!-- fields returned -->
<str name="fl">jobTitle,skill,company</str>
<!-- fields to match on-->
<str name="rf.fl">skillFromSkill,extractTitles</str>
<!-- field weights. Note that term weights are normalized so that each field is weighted exactly in this ratio
as different fields can get different numbers of matching terms-->
<str name="rf.qf">skillFromSkill^3 extractTitles^4.5</str>
<int name="rows">10</int>
<!-- How many terms to extract per field (max) -->
<int name="rf.maxflqt">10</int>
<bool name="rf.boost">true</bool>
<!-- normalize the weights for terms in each field (custom to dice rf, not present in solr MLT) -->
<bool name="rf.normflboosts">true</bool>
<!-- Take the raw term frequencies (false) or log of the term frequenies (true) -->
<bool name="rf.logtf">true</bool>
<!-- Minimum should match settings for the rf query - determines what proportion of the terms have to match -->
<!-- See Solr edismax mm parameter for specifics -->
<bool name="rf.mm">25%</bool>
<!-- Returns the top k terms (see regular solr MLT handler) -->
<str name="rf.interestingTerms">details</str>
<!-- Turns the rf query into a boost query using a multiplicative boost, allowing for boosting -->
<str name="rf.boostfn"></str>
<!-- q parameter - If you want to execute one query, and use the rf query to boost the results (e.g. for personalizing search),
pass the user's query into this parameter. Can take regular query syntax e.g.rf.q={!edismax df=title qf=.... v=$qq}&qq=Java
The regular q parameter is reserved for the rf query (see abpve)
-->
<str name="q"></str>
<!-- Query parser to use for the q query, if passed -->
<str name="defType"></str>
<!-- rf.q parameter - Note that the regular q parameter is used only for personalized search scenarios, where you have a main query
and you want to use the rf query generated to boost the main queries documents. Typically the rf.q query is a query that identifies
one or more documents, e.g. rf.q=(id:686867 id:98928980 id:999923). But it cam be any query. Note that it will process ALL documents
matched by the q query (as it's intended mainly for looking up docs by id), so use cautiously.
-->
<str name="rf.q"></str>
<!-- query parser to use for the rf.q query -->
<str name="rf.defType"></str>
<!-- Settings for personalized search - use the regular parameter names for the query parser defined by defType parameter -->
<str name="df">title</str>
<str name="qf"> company_text^0.01 title^12 skill^4 description^0.3</str>
<str name="pf2">company_text^0.01 title^12 skill^4 description^0.6</str>
<!-- Content based recommendations settings (post a document to the endpoint in a POST request). The stream.body and stream.head are form parameters
You can send them in a GET request, but a POST handles larger data. If you have really large documents, you will need to change the buffer settings
so that the request doesn't blow the buffer limits in Solr or your web server.
-->
<!-- Fields used for processing documents posted to the stream.body and stream.head parameters in a POST call -->
<str name="stream.head.fl">title,title_syn</str>
<str name="stream.body.fl">extractSkills,extractTitles</str>
<!-- pass a url in this parameter for Solr to download the webpage, and process the Html using the fields configured in the stream.qf parameters -->
<str name="stream.url"></str>
<!-- Note that we have two different content stream fields to pass over in the POST request. This allows different analyzers to be appkied to each.
For instance, we pass the job title into the stream.head field and parse out job titles, while we pass the job description to the stream.head parameter
to parse out skills -->
<!-- Pass the document body in this parameter as a form parameter. Analysed using the stream.body.fl fields-->
<str name="stream.body"></str>
<!-- Pass the second document field in this parameter. Analysed using the stream.head.fl fields-->
<str name="stream.head"></str>
<!-- Specifies a separate set of field weights to apply when procesing a document posted to the request handler via the
stream.body and stream.head parameters -->
<str name="stream.qf">extractSkills^4.5 extractTitles^2.25 title^3.0 title_syn^3.0</str>
</lst>
</requestHandler>
http:// localhost:8983/solr/jobs/rf?q = id:11f407d319d6cc707437fad874a097c0+id:a2fd2ff2e 34667D61FADCDCABFD359CF4&rows = 10&df = title&fl =タイトル、スキル、ジオコード、都市、州&WT = JSON
{
"match":{
"numFound":2,
"start":0,
"docs":[
{
"id":"a2fd2f2e34667d61fadcdcabfd359cf4",
"title":"Console AAA Sports Video Game Programmer.",
"skills":["Sports Game Experience a plus.",
"2-10 years plus Console AAA Video Game Programming Experience"],
"geocode":"38.124447,-122.55051",
"city":"Novato",
"state":"CA"
},
{
"id":"11f407d319d6cc707437fad874a097c0",
"title":"Game Engineer - Creative and Flexible Work Environment!",
"skills":["3D Math",
"Unity3d",
"C#",
"3D Math - game programming",
"game programming",
"C++",
"Java"],
"geocode":"33.97331,-118.243614",
"city":"Los Angeles",
"state":"CA"
}
]
},
"response":{
"numFound":5333,
"start":0,
"docs":[
{
"title":"Software Design Engineer 3 (Game Developer)",
"skills":["C#",
"C++",
"Unity"],
"geocode":"47.683647,-122.12183",
"city":"Redmond",
"state":"WA"
},
{
"title":"Game Server Engineer - MMO Mobile Gaming Start-Up!",
"skills":["AWS",
"Node.JS",
"pubnub",
"Websockets",
"pubnub - Node.JS",
"Vagrant",
"Linux",
"Git",
"MongoDB",
"Jenkins",
"Docker"],
"geocode":"37.777115,-122.41733",
"city":"San Francisco",
"state":"CA"
},...
]
}
}
solrconfig.xmlのリクエストハンドラー構成の例を以下に示し、主なパラメーターの概要を説明するコメントを示します。
<requestHandler name="/ufselect" class="org.dice.solrenhancements.unsupervisedfeedback.UnsupervisedFeedbackHandler">
<lst name="defaults">
<str name="omitHeader">true</str>
<str name="wt">json</str>
<str name="indent">true</str>
<!-- Regular query configuration -->
<str name="defType">edismax</str>
<str name="df">title</str>
<str name="qf">title^1.5 skills^1.25 description^1.1</str>
<str name="pf2">title^3.0 skills^2.5 description^1.5</str>
<str name="mm">1</str>
<str name="q.op">OR</str>
<str name="fl">jobTitle,skills,company</str>
<int name="rows">30</int>
<!-- Unsupervised Feedback (Blind Feedback) query configuration-->
<str name="uf.fl">skillsFromskills,titleFromJobTitle</str>
<!-- How many docs to extract the top terms from -->
<str name="uf.maxdocs">50</str>
<!-- How many terms to extract per field (max) -->
<int name="uf.maxflqt">10</int>
<bool name="uf.boost">true</bool>
<!-- Relative per-field boosts on the extracted terms (similar to edismax qf parameter -->
<!-- NOTE: with uf.normflboosts=true, all terms are normalized so that the total importance of each
field on the query is the same, then these relative boosts are applied per field-->
<str name="uf.qf">skillsFromskills^4.5 titleFromJobTitle^6.0</str>
<!-- Returns the top k terms (see regular solr MLT handler) -->
<str name="uf.interestingTerms">details</str>
<!-- unit-length norm all term boosts within a field (recommended) - see talk for details -->
<bool name="uf.normflboosts">true</bool>
<!-- use raw term clounts or log term counts? -->
<bool name="uf.logtf">false</bool>
</lst>
</requestHandler>
http:// localhost:8983/solr/dicejobscp/ufselect?q = machine+learning+engineer&start = 0&rows = 10&uf.logtf = false& fl =タイトル、スキル、ジオコード、都市、州&fq = {!geofilt+sfield = jobendecageocode+d = 48+pt = 39.6955、-105.0841}&wt = json
{
"match":
{
"numFound":7729,
"start":0,
"docs":[
{
"title":"NLP/Machine Learning Engineer",
"skills":["Linux",
"NLP (Natural Language Processing)",
"SQL",
"Bash",
"Python",
"ML (Machine Learning)",
"JavaScript",
"Java"],
"geocode":"42.35819,-71.050674",
"city":"Boston",
"state":"MA"
},
{
"title":"Machine Learning Engineer",
"skills":["machine learning",
"java",
"scala"],
"geocode":"47.60473,-122.32594",
"city":"Seattle",
"state":"WA"
},
{
"title":"Machine Learning Engineer - REMOTE!",
"skills":["Neo4j",
"Hadoop",
"gensim",
"gensim - C++",
"Java",
"R",
"MongoDB",
"elastic search",
"sci-kit learn",
"Python",
"C++"],
"geocode":"37.777115,-122.41733",
"city":"San Francisco",
"state":"CA"
},...
]
}
Solr MLTハンドラーコードとアルゴリズム(Rocchioアルゴリズムのみ)に大まかに基づいていますが、アルゴリズム設計にはいくつかの重要な違いがあります。 MLTハンドラーは、MLTクエリを構築するときに、構成されたすべてのフィールドで上部Kの用語を取得します。他のフィールドよりも広い語彙を持つフィールドがある場合、用語の平均文書頻度は、より小さな語彙を持つ他のフィールドよりも低くなります。これは、これらの用語が相対的なIDFスコアが高いことを意味し、SOLR MLTハンドラーによって選択された最高項を支配する傾向があります。リクエストハンドラーは、フィールドごとに上部Kの用語を取得します。また、RF.QFパラメーターで指定されているフィールド固有の重みが適用される前に、フィールドごとに何項が一致していても、そのフィールドは他のすべてのフィールドと同じ重み付けを他のすべてのフィールドと同じ重み付けしていることを保証します。これは、私たちが対処するSolr MLTハンドラーの2番目の問題です。また、多くの追加機能を提供します。コンテンツのストリームを渡すことができ、複数のドキュメントと一致し(「This」とは対照的に「これら」のようなもの)、Boostクエリパーサーを結果のMLTクエリに適用して、任意のsolrブーストを適用することができます(乗算)。また、MMパラメーターをサポートしているため、上位の用語のセット%のみにのみ一致するドキュメントを強制的に戻すことができます。
Lucene Revolution 2017の講演で実証されているように、検索パーソナライゼーションを実行するためにこれを使用する場合は、通常のQパラメーターを使用してユーザーの現在の検索クエリを渡す必要があり、ROCCHIOクエリを生成するために使用される情報は、RF.Qパラメーターを介して渡されます(ロッキオクエリを生成するためにドキュメントを使用する場合)。ただし、アルゴリズムが適用される正規化のプロセスにより、Rocchioクエリの用語に適用されるブーストは、ユーザークエリの重みと比較されていないことに注意してください。したがって、検索構成に基づいて、クエリに適切なレベルの影響が見つかるまで、異なるRF.QF値を試す必要があります。また、各ユーザーに対して生成されたRocchioクエリがユーザーの検索セッション全体で同じである可能性が高いことを考えると(もちろんユースケースに応じて)、これを使用するためにより効率的な方法は、RFハンドラーを使用してロチオクエリを使用して、ユーザーがこのクエリをキャッシュし、ハンドラーのクエリを使用して(ハンドラーのクエリを使用します)。ハンドラーは、応答のRF.QueryパラメーターのRocchioクエリを返します。クエリを取得するためだけにハンドラーを使用する場合(検索を実行しない)場合は、行パラメーターを0に設定できます。RF.INTERESTINGTERMS=詳細を設定し、これを使用してBoost Queryを作成する場合、Weightsとともに「興味深い用語」のセットを重みとともに繰り返すこともできます。
これがより多くのバージョンのSOLRで機能することを確認することは別として(あなたが望むバージョンについてフィードバックを残してください)、多くの可能な機能強化があります。
機能リクエストがある場合は、問題リストに送信してください。質問がある場合は、それも投稿するのに適した場所ですが、ここに戻ってこない場合は[email protected]で私に連絡することもできます。