Les plugins Solr de DICE.com pour effectuer une recherche personnalisée et des recommandations (via le plugin de rétroaction de pertinence) et une recherche conceptuelle / sémantique (via le plugin de rétroaction non supervisé).
Un fichier JAR pré-construit se trouve dans le dossier ./target . Le projet contient un fichier maven pom.xml qui peut également être utilisé pour le construire à partir de la source.
S'il y a une version particulière de SOLR pour laquelle vous en avez besoin, veuillez créer un problème GitHub et je verrai ce que je peux faire. Pour le compiler manuellement pour une version spécifique, utilisez Maven pour compiler les plugins à l'aide du fichier pom.xml et mettez à jour les versions des bibliothèques Solr et Lucene dans ce fichier et utilisez Maven pour extraire ces dépendances. Corrigez ensuite toutes les erreurs de compilation.
Veuillez consulter les directives officielles de SOLR pour l'enregistrement des plugins avec SOLR. Cela implique essentiellement de simplement supprimer le fichier JAR dans l'un des dossiers que SOLR vérifie les fichiers de classe et de jar sur le rechargement de base.
Un exemple de configuration de gestionnaire de demande pour le solrconfig.xml est illustré ci-dessous, avec des commentaires décrivant les principaux paramètres:
<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: a2fd2f2e 34667d61fadcdcabfd359cf4 & lignes = 10 & df = title & fl = title, compétences, géocode, ville, état & 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"
},...
]
}
}
Un exemple de configuration de gestionnaire de demande pour le solrconfig.xml est illustré ci-dessous, avec des commentaires décrivant les principaux paramètres:
<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 / dicejobspp / ufselect? q = machine + apprentissage + ingénieur & start = 0 & rows = 10 & uf.logtf = false & fl = titre, compétences, géocode, ville, état et 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"
},...
]
}
Bien qu'il soit vaguement basé sur le code et l'algorithme Solr MLT Handler (qui est juste l'algorithme Rocchio), il existe des différences clés dans la conception de l'algorithme. Le gestionnaire MLT prend les termes supérieurs dans tous les champs configurés lors de la construction de la requête MLT. Si vous avez un champ qui a un vocabulaire plus large que les autres champs, la fréquence moyenne du document d'un terme sera inférieure à celle des autres champs avec des vocabulaires plus petits. Cela signifie que ces termes auront des scores IDF relatifs élevés et ont tendance à dominer les termes supérieurs sélectionnés par le gestionnaire SOLR MLT. Notre gestionnaire de demandes prend les termes K Top par champ. Il garantit également que, quel que soit le nombre de termes correspondant par champ (jusqu'à la limite configurée), ce champ a la même pondération dans la requête résultante que tous les autres champs, avant les poids spécifiques du champ spécifié dans le paramètre RF.QF. Il s'agit du deuxième problème avec le gestionnaire Solr MLT que nous abordons. Nous offrons également beaucoup de fonctionnalités supplémentaires. Nous permettons de transmettre des flux de contenu, correspondant à plusieurs documents (plus comme «ceux-ci» par opposition à plus comme «ceci»), en appliquant l'analyseur de requête Boost à la requête MLT résultante pour permettre à tout boost solr arbitraire à appliquer (multiplicatif). Et nous prenons en charge le paramètre MM, afin que nous puissions forcer les documents à revenir qui ne correspondent qu'à un% des termes les plus élevés.
Si vous souhaitez l'utiliser pour effectuer une personnalisation de la recherche, comme le montre mon discours de Lucene Revolution 2017, vous devez transmettre la requête de recherche actuelle de l'utilisateur à l'aide du paramètre Q ordinaire, et les informations utilisées pour générer la requête Rocchio sont passées via le paramètre RF.Q (lors de l'utilisation de documents pour générer la requête Rocchio) ou via le contenu des paramètres du contenu). Notez cependant que les boosts appliqués aux termes de la requête Rocchio ne sont pas de poids comparatifs à ceux de votre requête utilisateur, en raison du processus de normalisation que l'algorithme s'applique. Vous devrez donc expérimenter différentes valeurs RF.QF jusqu'à ce que vous trouviez le bon niveau d'influence sur votre requête, en fonction de votre configuration de recherche. De plus, étant donné que la requête Rocchio générée pour chaque utilisateur est probablement la même dans toute la session de recherche de l'utilisateur (selon votre cas d'utilisation), une façon plus efficace de l'utiliser pour faire la personnalisation est simplement d'utiliser le gestionnaire RF pour générer la requête Rochio pour vous une fois lorsque le journal de recherche régulière est en cache pour la recherche sur la recherche de personnalisation. Le gestionnaire renvoie la requête Rocchio dans le paramètre RF.Query dans la réponse. Si vous souhaitez utiliser le gestionnaire juste pour obtenir la requête (et ne pas exécuter la recherche), vous pouvez définir le paramètre des lignes sur 0. Vous pouvez également itérer sur l'ensemble des `` termes intéressants '' renvoyé par l'algorithme, ainsi que leurs poids, si vous définissez RF.Intestingterms = Détails, et utilisez-le pour construire votre requête Boost.
En plus de garantir que cela fonctionne avec plus de versions de SOLR (veuillez laisser des commentaires sur les versions que vous souhaitez tous), il existe un certain nombre d'améliorations possibles:
Si vous avez une demande de fonctionnalité, veuillez le soumettre à la liste des problèmes. Si vous avez des questions, c'est aussi un bon endroit pour les publier, mais vous pouvez également me contacter à [email protected] si vous ne le faites pas ici.