Een van de kernfuncties van RDocumentation.org is de zoekfunctionaliteit. Vanaf het begin wilden we een supereenvoudige zoekbalk waarmee je vindt wat je zoekt, zonder een complex formulier dat vraagt om een pakketnaam, functienaam, versies of iets anders. Gewoon een eenvoudige zoekbalk.
In de technische blog van vandaag lichten we de technologieën en technieken uit die we gebruiken om relevante en betekenisvolle resultaten te bieden aan onze gebruikers.
Elasticsearch
RDocumentation.org gebruikt Elasticsearch om alle R-pakketten en -onderwerpen te indexeren en door te zoeken.
Elasticsearch is een open-source, schaalbare, gedistribueerde, enterprise-grade zoekmachine.
Elasticsearch is perfect voor het doorzoeken van documentatie, omdat het geen conventionele SQL-gegevens gebruikt, maar documenten opslaat in een JSON-achtige datastructuur. Elk document is gewoon een set key-value-paren met eenvoudige datatypes (strings, getallen, lijsten, datums, …). Door zijn gedistribueerde aard kan Elasticsearch extreem snel zijn.
Een Elasticsearch-cluster kan meerdere indexen hebben en elke index kan meerdere documenttypen hebben. Een documenttype beschrijft simpelweg hoe de structuur van het document eruit moet zien. Wil je meer weten over Elasticsearch-typen, bekijk dan de gids op elastic.co.
RDocumentation.org gebruikt drie verschillende typen: package_version, topic en package. De eerste twee zijn de belangrijkste; package bespreken we later.
Omdat RDocumentation.org open-source is, kun je de mappings van Elasticsearch bekijken in onze github-repo.
package_version type
Het type package_version is als een vertaling van het DESCRIPTION-bestand van een pakket; het bevat de belangrijkste velden die je daarin vindt: package_name, version, title, description, release_date, license, url, copyright, created_at, updated_at, latest_version, maintainer en collaborators. De maintainer en collaborators worden gehaald uit het veld Authors in het DESCRIPTION-bestand.
topic type
De topicdocumenten worden geparsed uit de Rd-bestanden, het standaardformaat voor documentatie in R. Het type topic heeft de volgende sleutels: name, title, description, usage, details, value, references, note, author, seealso, examples, created_at, updated_at, sections, aliases en keywords.
Scoring in Elasticsearch
Voordat er gescoord wordt, probeert Elasticsearch eerst de set kandidaten te verkleinen door te controleren of het document daadwerkelijk overeenkomt met de query. In essentie is een query een woord (of een set woorden). Op basis van de query-instellingen zoekt Elasticsearch naar een match in bepaalde velden van bepaalde typen.
Een match betekent echter niet per se dat het document relevant is; hetzelfde woord kan in verschillende contexten andere betekenissen hebben. Op basis van de query-instellingen kunnen we filteren op type en veld, en meer contextuele informatie opnemen. Deze context verbetert de relevantie en dit is waar scoring om de hoek komt kijken.
Elasticsearch gebruikt onder de motorkap Lucene, dus de scoring is gebaseerd op Lucenes Practical Scoring Function, die modellen samenbrengt zoals TF-IDF, het Vector Space Model en het Boolean Model om het document te scoren.
Wil je meer leren over hoe die functie in Elasticsearch wordt gebruikt, bekijk dan dit onderdeel van de elastic.co-gids.
Een manier om de relevantie te verbeteren is een boost toepassen op sommige velden. In de volledige zoekopdracht van RDocumentation.org boosten we bijvoorbeeld logischerwijs velden als package_name en title voor pakketten en aliases en name voor topics.
Populaire documenten boosten
Een andere effectieve manier om relevantie te verbeteren, is documenten boosten op basis van hun populariteit. Het idee daarachter is dat als een pakket populairder is, de gebruiker waarschijnlijker naar dit pakket zoekt. Door de populairdere pakketten eerst te tonen, vergroten we de kans dat we tonen waar de gebruiker daadwerkelijk naar op zoek is.
Downloads gebruiken als populariteitsmaat
Er zijn meerdere manieren om populariteit te meten. We zouden directe maten kunnen gebruiken zoals stemmen of beoordelingen die gebruikers geven (zoals ratings op Amazon-producten), of indirecte maten zoals het aantal verkochte items of het aantal weergaven (voor YouTube-video's).
Bij RDocumentation.org kozen we voor dat laatste. Meer specifiek gebruiken we het aantal downloads als maat voor populariteit. Indirecte maten zijn doorgaans makkelijker te verzamelen omdat ze geen actieve input van gebruikers vereisen.
Tijdskader
Een probleem dat ontstaat bij het gebruik van het aantal downloads, is dat oude pakketten van nature meer totale downloads zullen hebben dan nieuwere pakketten. Dat betekent niet dat ze populairder zijn; ze zijn simpelweg langer beschikbaar. Wat als een pakket jaren geleden erg populair was, maar inmiddels verouderd is en niet langer actief wordt gebruikt door de community?
Om dit op te lossen, nemen we alleen het aantal downloads in de afgelopen maand mee. Zo wordt de populariteitsscore van oudere pakketten niet kunstmatig opgekrikt en zullen verouderde pakketten snel wegzakken.
Directe vs. indirecte downloads
Een ander probleem ontstaat door reverse dependencies. R-pakketten zijn doorgaans afhankelijk van een breed scala aan andere pakketten. Pakketten met veel reverse dependencies worden daardoor veel vaker gedownload dan andere. Deze pakketten zijn echter meestal meer low-level en worden niet direct door de eindgebruiker gebruikt. We moeten ervoor waken hun aantal downloads niet te zwaar te laten meewegen.
Neem als voorbeeld Rcpp. Meer dan 70 procent van alle pakketten op CRAN, het comprehensive R archive network, is afhankelijk van dit pakket, wat het uiteraard het meest gedownloade R-pakket maakt. Toch zullen relatief weinig R-gebruikers dit pakket direct gebruiken en naar de documentatie ervan zoeken.
Om dit op te lossen, moesten we directe downloads (downloads die plaatsvinden omdat een gebruiker erom vraagt) en indirecte downloads (downloads die plaatsvinden omdat een afhankelijk pakket werd gedownload) scheiden. Om directe en indirecte downloads te onderscheiden in de CRAN-logs, gebruiken we dezelfde heuristiek als beschreven in het cran.stats-pakket van Arun Srinivasan.
We hebben nu een betekenisvolle populariteitsmetric: het aantal directe downloads in de afgelopen maand. Elasticsearch biedt een eenvoudige manier om deze extra informatie in te brengen; voor meer details, bekijk dit artikel op elastic.co.
De score wordt als volgt aangepast:
new_score = old_score * log(1 + number of direct downloads in the last month)
We gebruiken een log()-functie om de waarde number of downloads af te vlakken, omdat elke extra download minder gewicht heeft; het verschil tussen 0 en 1000 downloads zou meer impact moeten hebben op een populariteitsscore dan het verschil tussen 100.000 en 101.000 downloads.
Deze her-scoring verbetert de algehele relevantie van de zoekresultaten die RDocumentation.org presenteert, waardoor gebruikers zich kunnen richten op het lezen van documentatie in plaats van ernaar te zoeken.
Wil je meer weten over hoe de Elasticsearch-query precies is geïmplementeerd, bekijk dan het RDocumentation-project op GitHub. De query zelf staat in de SearchController.
Wil je meer leren over hoe RDocumentation.org is geïmplementeerd, bekijk dan onze repo's:
- RDocumentation-app: De webapplicatie die rdocumentation.org draait.
- RDocumentation-elasticsearch: Configuratie en feeders van de Elasticsearch-server achter rdocumentation.org.
- RDocumentation: R-pakket om rdocumentation.org in je R-werkflow te integreren
- RDocumentation-lambda-worker: AWS Lambda-pijplijn om pakketdocumentatie te parsen voor rdocumentation.org
Over RDocumentation
RDocumentation verzamelt helpdocumentatie voor R-pakketten van CRAN, BioConductor en GitHub — de drie meest voorkomende bronnen van actuele R-documentatie. RDocumentation.org gaat echter verder dan het simpelweg aggregeren van deze informatie, door al deze documentatie binnen handbereik te brengen via het RDocumentation-pakket. Het RDocumentation-pakket overschrijft de basishulpfuncties uit het utils-pakket en geeft je toegang tot RDocumentation.org vanuit het comfort van je RStudio IDE. Zoek de nieuwste en populairste R-pakketten op, doorzoek documentatie en plaats communityvoorbeelden.

