Skip to content

Commit

Permalink
Merge pull request #2093 from AnaelKremer/patch-2
Browse files Browse the repository at this point in the history
Update query-openalex.ini
  • Loading branch information
parmentf authored Jul 12, 2024
2 parents 6b0382d + 69248f0 commit 8797bee
Showing 1 changed file with 44 additions and 43 deletions.
87 changes: 44 additions & 43 deletions workers/loaders/query-openalex.ini
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Loader spécfique pour constituer un corpus à partir d'une requete OpenAlex sur les "works"
## ! Les identifiants des "works" sont transformés en uris afin de pouvoir tester plusieurs requêtes sans avoir de doublons [D].
### Afin de détecter puis retirer les mauvaises affiliations d'OpenAlex, on filtre les noms normalisés du laboratoire requêté et on retourne les adresses originales [A].
### Celles-ci sont ensuite testées à partir de regex afin de determiner si elles sont correctes ou non, il est impératif de modifier ce script [B].
### Enfin l'instruction [C] permet de retirer les notices récupérées par erreur. Il est nécessaire d'annuler cette instruction dans un premier temps, afin de pouvoir tester
### la validité des regex et de connaître les mauvaises affiliations. Les champs "apil_filtered_raw_affiliation_strings" [A] et "apil_filtered_and_tested_raw_affiliation_strings" [B]
### sont ensuite supprimés. Ils peuvent être conservés en les enlevant du tableau dans l'instruction [F].
## Les champs préfixés par "inist" sont des champs ayant subis des transformations, pour les autres ce sont les champs originax d'OpenAlex.
### ! Les identifiants des "works" sont transformés en uris afin de pouvoir tester plusieurs requêtes sans avoir de doublons [D].
#### Afin de détecter puis retirer les mauvaises affiliations d'OpenAlex, on filtre les noms normalisés du laboratoire requêté et on retourne les adresses originales [A].
#### Celles-ci sont ensuite testées à partir de regex afin de determiner si elles sont correctes ou non, il est impératif de modifier ce script [B].
#### Enfin l'instruction [C] permet de retirer les notices récupérées par erreur. Il est nécessaire d'annuler cette instruction dans un premier temps, afin de pouvoir tester
#### la validité des regex et de connaître les mauvaises affiliations. Les champs "inist_filtered_raw_affiliation_strings" [A] et "inist_filtered_and_tested_raw_affiliation_strings" [B]
#### sont ensuite supprimés. Ils peuvent être conservés en les enlevant du tableau dans l'instruction [F].

append = pack
label = query-openalex
Expand Down Expand Up @@ -81,38 +82,38 @@ value = env('query').thru(string => string.match(/i\d+/)).toUpper()
# Exemple pour le laboratoire GANIL
#[A] On récupère dans un premier temps les adresses originales qu'OpenALex a identifié comme relevant du laboratoire requêté.
#[assign]
#path = apil_filtered_raw_affiliation_strings
#path = inist_filtered_raw_affiliation_strings
#value = get("authorships").filter(obj => obj.institutions.some(obj => obj.id === `https://openalex.org/${self.lodexStamp.queryIdentifier}`)).flatMap(obj => obj.raw_affiliation_strings)

#[B] Dans un second temps on teste des regex pour vérifier que les adresses originales matchent bien avec le laboratoire requêté.
#[assign]
#path = apil_filtered_and_tested_raw_affiliation_strings
#value = get("apil_filtered_raw_affiliation_strings").some(item => /ganil/i.test(item) || /grand acc.*national.*ions.*lourds/i.test(item) || /Large heavy ion Nat.*acc.*/i.test(item))
[assign]
path = inist_filtered_and_tested_raw_affiliation_strings
value = get("inist_filtered_raw_affiliation_strings").some(item => /ganil/i.test(item) || /grand acc.*national.*ions.*lourds/i.test(item) || /Large heavy ion Nat.*acc.*/i.test(item))

#[C] Enfin on supprime les notices non pertinentes.
#[remove]
#test = get("apil_filtered_and_tested_raw_affiliation_strings").isEqual(false)
#test = get("inist_filtered_and_tested_raw_affiliation_strings").isEqual(false)
# }}}

[assign]
#[D]
path = uri
value = get('id').replace('https://openalex.org/', '')

path = apil_doi
path = inist_doi
value = get('doi').replace("https://doi.org/","").toLower()

path = apil_is_oa
path = inist_is_oa
value = get("open_access.is_oa").replace(false,"Non").replace(true,"Oui")

path = apil_keywords
path = inist_keywords
value = get('keywords').map('display_name')

path = author_name
value = get('authorships').map("author.display_name")

#[E] On récupère uniquement les auteurs du laboratoire requêté.
path = apil_filtered_author_name
path = inist_filtered_author_name
value = get("authorships").filter(obj => obj.institutions.some(obj => obj.id === `https://openalex.org/${self.lodexStamp.queryIdentifier}`)).flatMap(obj => obj.author.display_name)

path = institutions
Expand All @@ -121,111 +122,111 @@ value = get('authorships').flatMap("institutions").map("display_name").uniq()
path = source
value = get("primary_location.source.display_name")

path = apil_oa_status
path = inist_oa_status
value = get("apc_list.value").replace(/^(?!0$).*$/,"").replace(/^0$/,"diamond").concat(self.open_access.oa_status).compact().reduce((acc, v) => {if (v === "diamond") {return ["diamond"]} {return acc}},)

path = is_retracted
value = get("is_retracted").replace(false,"Non").replace(true,"Oui")

path = apil_pages
path = inist_pages
value = get("biblio.first_page").concat(self.biblio.last_page).uniq().join(" to ")

path = apil_volume
path = inist_volume
value = get("biblio.volume")

path = apil_issue
path = inist_issue
value = get("biblio.issue")

path = apil_classification
path = inist_classification
value = get("topics").map(item => `1 - ${item.domain.display_name}@2 - ${item.field.display_name}@3 - ${item.subfield.display_name}@4 - ${item.display_name}`).map(item=>item.split("@"))

path = apil_domains
path = inist_domains
value = get("topics").map("domain.display_name")

path = apil_fields
path = inist_fields
value = get("topics").map("field.display_name")

path = apil_subfields
path = inist_subfields
value = get("topics").map("subfield.display_name")

path = apil_topics
path = inist_topics
value = get("topics").map("display_name")

path = apil_collaborations_internationales
path = inist_collaborations_internationales
value = get("authorships").flatMap("countries").uniq().pull("FR").thru(arr=>!_.isEmpty(arr)).replace("true","Oui").replace("false","Non")


# On récupère un tableau d'objets, puis on itère sur chaque objet avec un template string pour en faire une chaîne de caractères.
# Chaque chaîne est préfixée par "Goal", on récupère ensuite les derniers chiffres de la variable "id" qui correspond au numéro du goal.
# On ajoute enfin la variable "display_name" qui est le nom du goal.
path=apil_sustainable_development_goals
path=inist_sustainable_development_goals
value=get("sustainable_development_goals").map( item => `Goal ${item.id.match(/\/sdg\/(\d+)/)[1]} : ${item.display_name}`).thru(arr => _.isEmpty(arr) ? ["No sustainable development goal"] : arr)

path = apil_funder_display_name
path = inist_funder_display_name
value = get("grants").map("funder_display_name").uniq()

# On récupère le nom des funders et leur id sous forme de matrice. On utilise ensuite _.compact dans chaque tableau pour que le _.join après ne concatène pas en cas d'absence de valeur à id,
# de sorte à ne pas avoir de valeur comme "funder : ". Le _.join sert à transformer la matrice en un seul tableau. On remplace ensuite les tableaux vides par ["n/a"].
path = apil_funders_award_id
path = inist_funders_award_id
value = get("grants").map(obj=>[obj.funder_display_name,obj.award_id]).map(subarr=>_.compact(subarr)).map(subarr => subarr.join(" : ")).thru(arr => _.isEmpty(arr) ? ["n/a"] : arr)

# On teste si dans la liste des urls où sont déposés les "works", au moins une appartient à un portail Hal.
# La regex couvre l'ensemble des portails hal et la spécificité de leurs urls. (Oui et Non pour facette).
[assign]
path = apil_is_hal
path = inist_is_hal
value = get("locations").map("landing_page_url").compact().some(item=>(/[^a-zA-Z0-9]hal[^a-zA-Z0-9]/).test(item)).replace(false,"Non").replace(true,"Oui")

# On récupère le champ qui indique dans quelles bases bibliographiques sont indexés les "works".
# On concatène le champ "apil_is_hal", on retire les "Non" et transforme les "Oui" en "hal".
# On concatène le champ "inist_is_hal", on retire les "Non" et transforme les "Oui" en "hal".
[assign]
path = apil_indexed_in
value = get("indexed_in").concat(self.apil_is_hal).pull("Non").map(item=>item === "Oui" ? "hal" : item).sort()
path = inist_indexed_in
value = get("indexed_in").concat(self.inist_is_hal).pull("Non").map(item=>item === "Oui" ? "hal" : item).sort()

# On récupère l'éditeur de la revue. ([] si vide, nécessaire pour les instructions et fonctions futures).
[assign]
path = apil_publisher_only
path = inist_publisher_only
value = get("primary_location.source.host_organization_name","n/a")

# On récupère un tableau avec l'éditeur mais aussi, s'il en a, sa ou ses sociétés mères (3 niveaux de hiérarchie).
# L'ordre est aléatoire, on ne peut se baser sur l'index. (["n/a"] si vide, nécéssaire pour les instructions et fonctions futures).
[assign]
path = apil_linked_publishers
path = inist_linked_publishers
value = get("primary_location.source.host_organization_lineage_names",["n/a"])

# On compare les 2 champ créés au-dessus, pour retirer du tableau les éditeurs du plus-bas niveau de hiérarchie.
# Si publisherOnly était au plus haut niveau (0) on obtient [].
# S'il était au niveau 1 on obtient son niveau supérieur (0).
# S'il était au plus bas on obtient ses 2 sociétés mères (0 & 1).
[assign]
path = apil_xor_publisher
value = get("apil_publisher_only").castArray().xor(self.apil_linked_publishers)
path = inist_xor_publisher
value = get("inist_publisher_only").castArray().xor(self.inist_linked_publishers)

# On isole tous les tableaux vides.
[swing]
test = get("apil_xor_publisher").isEmpty()
test = get("inist_xor_publisher").isEmpty()

# On leur réattribue leur unique valeur.
[swing/assign]
path = apil_xor_publisher
value = get("apil_publisher_only")
path = inist_xor_publisher
value = get("inist_publisher_only")

# On associe le tout, ne reste plus que le cas des tableaux avec niveaux 0 et 1.
# On retire les parents directs des éditeurs de niveau 2, on n'a donc plus que les éditeurs du plus haut niveau.
[assign]
path = apil_publisher
value = get("apil_xor_publisher").pull("Springer Science+Business Media","Vandenhoeck & Ruprecht","University of California, Berkeley","University of California, Los Angeles","Siberian Branch of the Russian Academy of Sciences").toString().replace(null,"n/a").replace(undefined,"n/a")
path = inist_publisher
value = get("inist_xor_publisher").pull("Springer Science+Business Media","Vandenhoeck & Ruprecht","University of California, Berkeley","University of California, Los Angeles","Siberian Branch of the Russian Academy of Sciences").toString().replace(null,"n/a").replace(undefined,"n/a")

# On recupère l'abstract sous forme d'un tableau d'objets où keys sont les mots et values leur(s) position(s) dans l'abstract ([{"the":[0,12,25]}...]).
# Les keys contiennent donc des "." ou autres caractères spéciaux proscrits MongoDB Node.js driver.
# On transforme cela en un tableau où chaque value est "key:value", on découpe pour avoir une matrice. On parse les values en base 10 pour obtenir des entiers.
# On inverse ensuite les éléments dans chaque sous-tableau de la matrice. On effectue un tri dans la matrice, on ne garde plus que les mots et transforme le tout en un string.
[assign]
path = apil_abstract
path = inist_abstract
value = get("abstract_inverted_index").flatMap((values, key) => {return values.map(value => `${key}:${value}`) }).map(item => item.split(":")).map(([first, second]) => [first, parseInt(second, 10)]).map(item => item.reverse()).sort((a, b) => a[0] - b[0]).map(item => item.slice(1)).flatMap().join(' ')

#[F]
[exchange]
value = omit(["topics","concepts","grants","datasets","versions","is_authors_truncated","apil_filtered_raw_affiliation_strings","apil_filtered_and_tested_raw_affiliation_strings","doi","biblio","abstract_inverted_index","indexed_in","display_name","apil_publisher_only","apil_xor_publisher","publication_date","countries_distinct_count","institutions_distinct_count","corresponding_author_ids","corresponding_institution_ids","has_fulltext","fulltext_origin","cited_by_percentile_year","is_paratext","primary_topic","keywords","locations_count","referenced_works","related_works","ngrams_url","cited_by_api_url","created_date","updated_date","sustainable_development_goals"])
value = omit(["topics","concepts","grants","datasets","versions","is_authors_truncated","inist_filtered_raw_affiliation_strings","inist_filtered_and_tested_raw_affiliation_strings","doi","biblio","abstract_inverted_index","indexed_in","display_name","inist_publisher_only","inist_xor_publisher","publication_date","countries_distinct_count","institutions_distinct_count","corresponding_author_ids","corresponding_institution_ids","has_fulltext","fulltext_origin","cited_by_percentile_year","is_paratext","primary_topic","keywords","locations_count","referenced_works","related_works","ngrams_url","cited_by_api_url","created_date","updated_date","sustainable_development_goals"])

# }}}

Expand Down

0 comments on commit 8797bee

Please sign in to comment.