diff --git a/README.md b/README.md index d5a0294..6b8f0c0 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,14 @@ pubmed.search("actin", 0, 20).then((results) => { }); ``` +You can also search by relevance (instead of publication date): + +```javascript +pubmed.searchByRelevance("actin").then((results) => { + console.log(results); +}); +``` + ### Looking up a specific paper ```javascript @@ -84,6 +92,14 @@ In addition, following methods are available: All methods return a promise accessible by `.then()`; the value retrieved is passed to the promise. +### Searching by PubMedCentral (PMC) ID number + +```javascript +pmc.summary(3315798).then((paper) => { + console.log(paper); +}); +``` + ## Contributing I'd love to get PRs improving the code or expanding the search methods beyond PubMed. diff --git a/src/gateways/index.js b/src/gateways/index.js index fcb7ba7..9d8005a 100644 --- a/src/gateways/index.js +++ b/src/gateways/index.js @@ -1,55 +1,65 @@ -'use strict'; +"use strict"; -const createGateway = require('./createGateway'); +const createGateway = require("./createGateway"); /** * Wrapper factory functions for the Gateway. Create and configure Gateways * for a specific purpose. */ module.exports = { - /** * pubmedSearch. Return a Gateway for a pubmed search, with start and end parameters. * (ie first and last results.) */ - pubmedSearch: function(query, page, resultsPerPage) { + pubmedSearch: function (query, page, resultsPerPage, sort) { const start = page * resultsPerPage; return createGateway({ - utility: 'esearch', + utility: "esearch", params: { - db: 'pubmed', + db: "pubmed", term: query, retstart: start, - retmax: resultsPerPage - } + retmax: resultsPerPage, + sort: sort, + }, }); }, /** * pubmedSummary. Get a set of pubmedSummaries, specified by an array of pmid (pubmed identifiers.) */ - pubmedSummary: function(ids) { + pubmedSummary: function (ids) { + return createGateway({ + utility: "esummary", + params: { + db: "pubmed", + id: ids, + }, + }); + }, + + pmcSummary: function (ids) { return createGateway({ utility: 'esummary', params: { - db: 'pubmed', - id: ids + db: 'pmc', + id: ids, } - }); + }) }, /** - * Get a set of full/efetch documents from pubmed, specified by an array of pmids (pubmed identifiers). - * Note that efetch documents can only be returned via XML (or flatfile). - */ - pubmedRecord: function(ids) { + * Get a set of full/efetch documents from pubmed, specified by an array of pmids (pubmed identifiers). + * Note that efetch documents can only be returned via XML (or flatfile). + */ + pubmedRecord: function (ids) { return createGateway({ - utility: 'efetch', + utility: "efetch", params: { - db: 'pubmed', - retmode: 'xml', - id: ids - } + db: "pubmed", + retmode: "xml", + id: ids, + }, }); }, @@ -59,25 +69,25 @@ module.exports = { * similar articles, articles that cite this article, and articles cited by * this article. */ - pubmedLinks: function(id) { + pubmedLinks: function (id) { return createGateway({ - utility: 'elink', + utility: "elink", params: { - db: 'pubmed', - dbfrom: 'pubmed', - cmd: 'neighbor', - id: id - } + db: "pubmed", + dbfrom: "pubmed", + cmd: "neighbor", + id: id, + }, }); }, - pmcFullText: (id) => createGateway({ - utility: 'efetch', - params: { - db: 'pmc', - retmode: 'xml', - id: id - } - }) - -} + pmcFullText: (id) => + createGateway({ + utility: "efetch", + params: { + db: "pmc", + retmode: "xml", + id: id, + }, + }), +}; diff --git a/src/pmc.js b/src/pmc.js new file mode 100644 index 0000000..75c716c --- /dev/null +++ b/src/pmc.js @@ -0,0 +1,17 @@ +'use strict'; + +const gateways = require('./gateways'); +const queries = require('./queries'); + +module.exports = { + summary: function(pmc) { + return gateways.pmcSummary(pmc).resolve(data => { + const summaries = queries.summaries(data); + if (summaries.length) { + return summaries[0]; + } else { + return null; + } + }); + } +} \ No newline at end of file diff --git a/src/pubmed.js b/src/pubmed.js index 4912e6d..5dd3b21 100644 --- a/src/pubmed.js +++ b/src/pubmed.js @@ -3,30 +3,37 @@ const gateways = require('./gateways'); const queries = require('./queries'); +function pubmedSearch(query, page, resultsPerPage, sort) { + let count; + page = page || 0; + resultsPerPage = resultsPerPage || 10; + sort = sort || 'most+recent' + return gateways.pubmedSearch(query, page, resultsPerPage).resolve(data => { + count = queries.count(data); + const pmids = queries.ids(data); + if (!pmids.length) { + return { + count: 0, + papers: [] + }; + } + return new Promise((resolve, reject) => { + this.summaries(pmids).then(summaries => { + resolve({ + count: count, + papers: summaries + }); + }).catch(err => reject(err)); + }); + }); +} + module.exports = { - search: function(query, page, resultsPerPage) { - let count; - page = page || 0; - resultsPerPage = resultsPerPage || 10; - return gateways.pubmedSearch(query, page, resultsPerPage).resolve(data => { - count = queries.count(data); - const pmids = queries.ids(data); - if (!pmids.length) { - return { - count: 0, - papers: [] - }; - } - return new Promise((resolve, reject) => { - this.summaries(pmids).then(summaries => { - resolve({ - count: count, - papers: summaries - }); - }).catch(err => reject(err)); - }); - }); + search: pubmedSearch, + + searchByRelevance: function(query, page, resultsPerPage) { + return pubmedSearch(query, page, resultsPerPage, 'relevance'); }, summaries: function(pmids) { diff --git a/src/queries/summaries.js b/src/queries/summaries.js index 3e0b351..2182835 100644 --- a/src/queries/summaries.js +++ b/src/queries/summaries.js @@ -12,15 +12,15 @@ const summaryQueries = { raw: data, title: data.title || '', authors: summaryQueries.formatAuthors(data.authors) || '', - pubDate: data.sortpubdate + pubDate: data.sortpubdate || data.sortdate, }; data.articleids.forEach((idObject) => { - if (idObject.idtype === 'pubmed') { + if (['pubmed', 'pmid'].includes(idObject.idtype)) { //Change pubmed to pmid. Make sure it's an integer. summary.pmid = parseInt(idObject.value, 10); } else if (idObject.idtype === 'pmc') { //Remove PMC from the beginning of the string and make sure it's an integer. - summary.pmc = parseInt(idObject.value.replace('PMC', '')); + summary.pmc = parseInt(idObject.value.replace('PMC', ''), 10); } else if (idObject.idtype === 'doi') { //Move DOI to the top level summary.doi = idObject.value; diff --git a/test/integration.js b/test/integration.js index f4dbe97..176ab35 100644 --- a/test/integration.js +++ b/test/integration.js @@ -5,6 +5,7 @@ const {isPubmedSummary} = require('./helpers.js'); const assert = require('assert'); var pubmed = require('../src/pubmed'); +var pmc = require('../src/pmc') describe('Pubmed module', function() { this.timeout(10000); @@ -72,6 +73,13 @@ describe('Pubmed module', function() { }); }); + it('should retrieve a summary from pmc', function(done) { + pmc.summary(3315798).then(result => { + isPubmedSummary(result); + done(); + }); + }); + it('should retrieve the full NLM XML of a paper', function(done) { pubmed.fulltext(22323294).then(result => { check.string(result); diff --git a/test/test.js b/test/test.js index e085a0f..ad5459a 100644 --- a/test/test.js +++ b/test/test.js @@ -40,6 +40,17 @@ describe('Links gateway', function() { }); +describe('PMC summary gateway', () => { + describe('generateUrl', () => { + + it('should build a valid url from parameters', () => { + const fetch = createGateway.pmcSummary(3315798); + assert.equal(fetch.generateUrl(), 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?retmode=json&db=pmc&id=3315798'); + }); + + }); +}); + describe('PMC full text gateway', () => { describe('generateUrl', () => { diff --git a/types/node-ncbi.d.ts b/types/node-ncbi.d.ts index c5e3927..a28625b 100644 --- a/types/node-ncbi.d.ts +++ b/types/node-ncbi.d.ts @@ -1,15 +1,15 @@ declare module "node-ncbi" { + interface Paper { + raw: object; + pubDate: string; + title: string; + authors: string; + pmid: number; + pmc?: number; + doi?: string; + } + module pubmed { - interface Paper { - raw: object; - pubDate: string; - title: string; - authors: string; - pmid: number; - pmc?: number; - doi?: string; - } - function search( term: string, page?: number, @@ -19,6 +19,15 @@ declare module "node-ncbi" { papers: Array; }>; + function searchByRelevance( + term: string, + page?: number, + limit?: number + ): Promise<{ + count: number; + papers: Array; + }>; + function summary(pmid: number): Promise; function summaries(pmids: string): Promise; @@ -35,4 +44,8 @@ declare module "node-ncbi" { function fullText(pmid: number): Promise; } + + module pmc { + function summary(pmc: number): Promise; + } }