Skill Tracer
Skills › Scientific Agent Skills › literature-review › database_strategies.md

database_strategies.md

183 lines · skills/literature-review/references/database_strategies.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Literature database search strategies
2
3Reviewed 2026-09-30. These are bibliographic discovery contracts, not a promise
4of complete retrieval. Save query, platform, date/time, date-field meaning,
5filters, raw pages, reported total, exported count, and any failures. Mark a
6capped or interrupted retrieval incomplete before screening it.
7

Literature database search strategies

Reviewed 2026-09-30. These are bibliographic discovery contracts, not a promise of complete retrieval. Save query, platform, date/time, date-field meaning, filters, raw pages, reported total, exported count, and any failures. Mark a capped or interrupted retrieval incomplete before screening it.

Raw lines 1 to 7
8## Source selection and query design
9
101. Define the review type and eligibility criteria before seeing results. Use
11 PICO for intervention questions; adapt the framework for other questions.
122. Select complementary bibliographic databases, relevant registries, preprint
13 servers, and grey literature sources. A web search and a biological entity
14 database are not substitutes for a discipline's bibliographic index.
153. Build synonym groups with OR and combine concepts with AND. Pilot against
16 known eligible papers. Consider whether outcome filters, language limits,
17 publication-type limits, or NOT terms discard relevant studies.
184. Translate each query to that platform. Wildcards and field syntax are not
19 portable: do not copy PubMed `[MeSH]`, arXiv `ti:`, or search-engine operators
20 into another API. Record the actual translated query, not just keywords.
215. For systematic reviews, screen against protocol criteria regardless of venue,
22 author reputation, institutional affiliation, or citation count. Bibliometric
23 metrics reflect exposure and field/age effects, not risk of bias.

Source selection and query design

  1. Define the review type and eligibility criteria before seeing results. Use PICO for intervention questions; adapt the framework for other questions.
  2. Select complementary bibliographic databases, relevant registries, preprint servers, and grey literature sources. A web search and a biological entity database are not substitutes for a discipline's bibliographic index.
  3. Build synonym groups with OR and combine concepts with AND. Pilot against known eligible papers. Consider whether outcome filters, language limits, publication-type limits, or NOT terms discard relevant studies.
  4. Translate each query to that platform. Wildcards and field syntax are not portable: do not copy PubMed [MeSH], arXiv ti:, or search-engine operators into another API. Record the actual translated query, not just keywords.
  5. For systematic reviews, screen against protocol criteria regardless of venue, author reputation, institutional affiliation, or citation count. Bibliometric metrics reflect exposure and field/age effects, not risk of bias.
Raw lines 8 to 24
25## PubMed and PMC
27Use the [PubMed interface](https://pubmed.ncbi.nlm.nih.gov/advanced/) or NCBI
28E-utilities. `gget search` searches Ensembl and has no PubMed/bioRxiv mode.
29PubMed contains bibliographic records; PMC is a full-text repository with a
30partly overlapping corpus. Do not equate access to an abstract with full text.
32A small first-page request, not a complete review search:
34```bash
35mkdir -p sources
36curl --fail-with-body --get 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi' \
37 --data-urlencode 'db=pubmed' \
38 --data-urlencode 'term=(CRISPR[Title/Abstract]) AND ("Anemia, Sickle Cell"[MeSH Terms])' \
39 --data-urlencode 'retmode=json' --data-urlencode 'retmax=5' \
40 --data-urlencode 'tool=literature_review' -o sources/pubmed-first-page.json
41```
43- ESearch returns `esearchresult.count` (often a string), `idlist`, and query
44 translation/warnings. Inspect these; HTTP 200 alone does not confirm success.
45- Use `retstart`/`retmax` for paging **within the first 10,000 PubMed matches**.
46 Partition larger searches into recorded, deduplicated subqueries or use a
47 documented bulk method; the History server does not bypass this limit.
48- EFetch is `GET .../efetch.fcgi?db=pubmed&id=PMID1,PMID2&retmode=xml` (or POST for
49 large ID sets). Parse `PubmedArticleSet` XML, preserve article/book records,
50 and reconcile requested versus returned IDs.
51- No key is needed for small requests. Supply a real contact `email` and `tool`
52 for sustained use; optional `api_key` raises the default shared limit from
53 3 requests/s per IP to 10/s per key. Account for concurrent clients.
54- Use explicit `[Publication Date]` ranges, and record the selected field.
55 A historical example such as `2020:2024[DP]` does not mean "current years".
57Sources: [NLM parameter guide](https://www.nlm.nih.gov/dataguide/eutilities/utilities.html),
58[PubMed 10,000-result ceiling](https://ncbiinsights.ncbi.nlm.nih.gov/2021/10/05/updated-pubmed-api/),
59[NCBI usage guidelines](https://eutilities.github.io/site/API_Key/usageandkey/).

PubMed and PMC

Use the PubMed interface or NCBI E-utilities. gget search searches Ensembl and has no PubMed/bioRxiv mode. PubMed contains bibliographic records; PMC is a full-text repository with a partly overlapping corpus. Do not equate access to an abstract with full text.

A small first-page request, not a complete review search:

mkdir -p sources
curl --fail-with-body --get 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi' \
  --data-urlencode 'db=pubmed' \
  --data-urlencode 'term=(CRISPR[Title/Abstract]) AND ("Anemia, Sickle Cell"[MeSH Terms])' \
  --data-urlencode 'retmode=json' --data-urlencode 'retmax=5' \
  --data-urlencode 'tool=literature_review' -o sources/pubmed-first-page.json
  • ESearch returns esearchresult.count (often a string), idlist, and query translation/warnings. Inspect these; HTTP 200 alone does not confirm success.
  • Use retstart/retmax for paging within the first 10,000 PubMed matches. Partition larger searches into recorded, deduplicated subqueries or use a documented bulk method; the History server does not bypass this limit.
  • EFetch is GET .../efetch.fcgi?db=pubmed&id=PMID1,PMID2&retmode=xml (or POST for large ID sets). Parse PubmedArticleSet XML, preserve article/book records, and reconcile requested versus returned IDs.
  • No key is needed for small requests. Supply a real contact email and tool for sustained use; optional api_key raises the default shared limit from 3 requests/s per IP to 10/s per key. Account for concurrent clients.
  • Use explicit [Publication Date] ranges, and record the selected field. A historical example such as 2020:2024[DP] does not mean "current years".

Sources: NLM parameter guide, PubMed 10,000-result ceiling, NCBI usage guidelines.

Raw lines 25 to 60
61## bioRxiv and medRxiv
63The [official API](https://api.biorxiv.org/) provides date/DOI metadata retrieval,
64not a general keyword query endpoint. Use the server's search interface for
65keyword discovery or filter the downloaded metadata explicitly.
67- `GET https://api.biorxiv.org/details/{server}/{from}/{to}/{cursor}/json`, with
68 server `biorxiv` or `medrxiv`, date strings `YYYY-MM-DD`, zero-based
69 cursor (start at 0), and optional `category=cell_biology`.
70- Response `collection[]` holds records; `messages[]` describes status, count,
71 cursor, and totals. Date-range calls return at most 30 records; advance the
72 cursor by the number received, retain all versions, and check totals/status.
73- Single DOI: `/details/{server}/{doi}/na/json`. Preserve DOI, `version`, `date`,
74 abstract, license, and `published` linkage. A preprint and a published report
75 may describe one study but are distinct reports.
76- `/pubs/{server}/{from}/{to}/{cursor}` maps publication links, with up to 100
77 entries per page. It has a different schema (`biorxiv_doi`, `published_doi`).
78- Public reads need no API key. Use conservative sequential calls and stop on
79 throttling/errors; do not interpret missing publication links as proof that
80 a preprint remains unpublished.

bioRxiv and medRxiv

The official API provides date/DOI metadata retrieval, not a general keyword query endpoint. Use the server's search interface for keyword discovery or filter the downloaded metadata explicitly.

  • GET https://api.biorxiv.org/details/{server}/{from}/{to}/{cursor}/json, with server biorxiv or medrxiv, date strings YYYY-MM-DD, zero-based cursor (start at 0), and optional category=cell_biology.
  • Response collection[] holds records; messages[] describes status, count, cursor, and totals. Date-range calls return at most 30 records; advance the cursor by the number received, retain all versions, and check totals/status.
  • Single DOI: /details/{server}/{doi}/na/json. Preserve DOI, version, date, abstract, license, and published linkage. A preprint and a published report may describe one study but are distinct reports.
  • /pubs/{server}/{from}/{to}/{cursor} maps publication links, with up to 100 entries per page. It has a different schema (biorxiv_doi, published_doi).
  • Public reads need no API key. Use conservative sequential calls and stop on throttling/errors; do not interpret missing publication links as proof that a preprint remains unpublished.
Raw lines 61 to 81
82## arXiv
84`GET https://export.arxiv.org/api/query` accepts `search_query`, `id_list`,
85`start` (zero-based), `max_results`, `sortBy`, and `sortOrder`. No key is needed.
87```bash
88curl --fail-with-body --get 'https://export.arxiv.org/api/query' \
89 --data-urlencode 'search_query=cat:q-bio.QM AND ti:"single cell"' \
90 --data-urlencode 'start=0' --data-urlencode 'max_results=5' \
91 --data-urlencode 'sortBy=submittedDate' --data-urlencode 'sortOrder=descending' \
92 -o sources/arxiv-first-page.xml
93```
95Parse Atom namespaces, `opensearch:totalResults`, and entry IDs; error entries
96can arrive in an Atom feed. Preserve `vN`, original `published`, and `updated`
97dates. `ti:` is the title field, not `title:`. Use a single connection with at
98least three seconds between requests. Use pages no larger than 2,000 and do
99not expect offsets to provide more than 30,000 matches; partition or use the
100bulk interfaces. This is preprint discovery, not evidence of peer review.
102Source: [arXiv API manual](https://info.arxiv.org/help/api/user-manual.html).

arXiv

GET https://export.arxiv.org/api/query accepts search_query, id_list, start (zero-based), max_results, sortBy, and sortOrder. No key is needed.

curl --fail-with-body --get 'https://export.arxiv.org/api/query' \
  --data-urlencode 'search_query=cat:q-bio.QM AND ti:"single cell"' \
  --data-urlencode 'start=0' --data-urlencode 'max_results=5' \
  --data-urlencode 'sortBy=submittedDate' --data-urlencode 'sortOrder=descending' \
  -o sources/arxiv-first-page.xml

Parse Atom namespaces, opensearch:totalResults, and entry IDs; error entries can arrive in an Atom feed. Preserve vN, original published, and updated dates. ti: is the title field, not title:. Use a single connection with at least three seconds between requests. Use pages no larger than 2,000 and do not expect offsets to provide more than 30,000 matches; partition or use the bulk interfaces. This is preprint discovery, not evidence of peer review.

Source: arXiv API manual.

Raw lines 82 to 103
104## Semantic Scholar
106Use the [Graph API contract](https://api.semanticscholar.org/api-docs/graph)
107(and its downloadable [schema](https://api.semanticscholar.org/graph/v1/swagger.json)).
109- Relevance search: `GET https://api.semanticscholar.org/graph/v1/paper/search`;
110 plain-text `query`, separate `year=2020-2024`, optional `fields`, `offset`,
111 `limit` (maximum 100). Response has `data[]`, `total`, and optional `next`.
112 Only 1,000 relevance-ranked records are retrievable; not an exhaustive export.
113- Bulk search: `GET .../paper/search/bulk`; query uses its documented Boolean
114 grammar (`+`, `|`, `-`, quotes, parentheses), with separate filters and
115 `fields`. Response has `data[]` and a continuation `token`; pass that token
116 unchanged to the next request. Up to 1,000 records/call, capped at 10 million.
117 Nested citation/reference data are not available on this endpoint.
118- Do not invent `title:`/`author:` operators for the relevance API. Use separate
119 author or title search routes only after consulting their own contracts.
120- API keys go in `x-api-key`; availability/quota depends on the endpoint and
121 account. Anonymous access is a shared, throttled pool. Follow your granted
122 quota, inspect HTTP 429, and back off; the former blanket "100 requests per
123 5 minutes" is not a current service guarantee.
124- Citation counts and influential-citation labels are discovery aids. Check
125 paper identity, missing fields, date coverage, and source text yourself.

Semantic Scholar

Use the Graph API contract (and its downloadable schema).

  • Relevance search: GET https://api.semanticscholar.org/graph/v1/paper/search; plain-text query, separate year=2020-2024, optional fields, offset, limit (maximum 100). Response has data[], total, and optional next. Only 1,000 relevance-ranked records are retrievable; not an exhaustive export.
  • Bulk search: GET .../paper/search/bulk; query uses its documented Boolean grammar (+, |, -, quotes, parentheses), with separate filters and fields. Response has data[] and a continuation token; pass that token unchanged to the next request. Up to 1,000 records/call, capped at 10 million. Nested citation/reference data are not available on this endpoint.
  • Do not invent title:/author: operators for the relevance API. Use separate author or title search routes only after consulting their own contracts.
  • API keys go in x-api-key; availability/quota depends on the endpoint and account. Anonymous access is a shared, throttled pool. Follow your granted quota, inspect HTTP 429, and back off; the former blanket "100 requests per 5 minutes" is not a current service guarantee.
  • Citation counts and influential-citation labels are discovery aids. Check paper identity, missing fields, date coverage, and source text yourself.
Raw lines 104 to 126
127## OpenAlex, Crossref, and supplementary search
129[OpenAlex authentication](https://help.openalex.org/api/authentication/) permits
130keyless casual reads; a free key raises the daily budget. Use `api_key` or
131`Authorization: Bearer` without saving secrets in search logs. `GET
132https://api.openalex.org/works` accepts `search`, `filter`, `select`, and `sort`.
133Responses have `results[]` and `meta`. The current `per_page` maximum is 100;
134start `cursor=*` and follow `meta.next_cursor` unchanged. Basic page-based
135retrieval stops at 10,000. Respect request credits and rate-limit headers;
136keyless does not mean unlimited. See [paging](https://help.openalex.org/api/paging/).
138Crossref `GET https://api.crossref.org/works/{doi}` is a singleton metadata
139lookup with JSON `message`, no key or pagination. A 404 does not prove a DOI
140from another registration agency is invalid. List searches (`/works?query...`)
141have different quotas and pagination: public list limit 1/s, polite 3/s, versus
1425/s and 10/s for single records. Provide real `mailto` for polite access; follow
143[response headers](https://community.crossref.org/t/refining-rest-api-limits-for-improved-stability-and-reliability/16137).
145Google Scholar's [interface](https://scholar.google.com/intl/en/scholar/help.html)
146provides Cited by, Related articles, and Cite exports, but no supported bulk API.
147Record queries and screened ranges; do not promise citation-count sorting,
148unlimited results, or complete coverage from a ranked sample. Stop on access
149blocks. Dimensions and licensed indexes require the access your institution
150actually holds; a free website tier does not imply API entitlement.

OpenAlex, Crossref, and supplementary search

OpenAlex authentication permits keyless casual reads; a free key raises the daily budget. Use api_key or Authorization: Bearer without saving secrets in search logs. GET https://api.openalex.org/works accepts search, filter, select, and sort. Responses have results[] and meta. The current per_page maximum is 100; start cursor=* and follow meta.next_cursor unchanged. Basic page-based retrieval stops at 10,000. Respect request credits and rate-limit headers; keyless does not mean unlimited. See paging.

Crossref GET https://api.crossref.org/works/{doi} is a singleton metadata lookup with JSON message, no key or pagination. A 404 does not prove a DOI from another registration agency is invalid. List searches (/works?query...) have different quotas and pagination: public list limit 1/s, polite 3/s, versus 5/s and 10/s for single records. Provide real mailto for polite access; follow response headers.

Google Scholar's interface provides Cited by, Related articles, and Cite exports, but no supported bulk API. Record queries and screened ranges; do not promise citation-count sorting, unlimited results, or complete coverage from a ranked sample. Stop on access blocks. Dimensions and licensed indexes require the access your institution actually holds; a free website tier does not imply API entitlement.

Raw lines 127 to 151
152## Result normalization and reproducibility
154`search_databases.py` does **not** query or merge raw provider envelopes. Give it
155a JSON array of normalized objects, preserving the raw exports separately:
157```json
159 {"title": "Example title", "authors": "Author, A. and Author, B.",
160 "first_author": "Author", "year": 2026, "source": "PubMed",
161 "doi": null, "url": "https://pubmed.ncbi.nlm.nih.gov/", "citations": null}
163```
165Use strings for title/authors/source and numbers or null for citation counts;
166BibTeX authors require `and` separators. Keep provider IDs, search/run IDs,
167retrieval dates, and source provenance as extra fields. Missing is not zero.
169```bash
170python scripts/search_databases.py combined_results.json --deduplicate \
171 --format json --output unique_results.json --summary
172```
174Deduplication keeps the first normalized DOI; title fallback compares DOI-less
175records only. Review title matches manually and enrich from raw duplicates;
176the script does not choose the most complete metadata or link all reports of a
177study. Unknown years remain for manual review. Ranking only orders the imported
178sample. Use final BibTeX keys from the export; same-author/year keys receive
179suffixes. An export timestamp is not the original search date.
181Use the official [PRISMA guidance](https://www.prisma-statement.org/prisma-2020)
182and [Cochrane selection guidance](https://www.cochrane.org/authors/handbooks-and-manuals/handbook/current/chapter-04)
183to keep screening decisions and report/study links auditable.

Result normalization and reproducibility

search_databases.py does not query or merge raw provider envelopes. Give it a JSON array of normalized objects, preserving the raw exports separately:

[
  {"title": "Example title", "authors": "Author, A. and Author, B.",
   "first_author": "Author", "year": 2026, "source": "PubMed",
   "doi": null, "url": "https://pubmed.ncbi.nlm.nih.gov/", "citations": null}
]

Use strings for title/authors/source and numbers or null for citation counts; BibTeX authors require and separators. Keep provider IDs, search/run IDs, retrieval dates, and source provenance as extra fields. Missing is not zero.

python scripts/search_databases.py combined_results.json --deduplicate \
  --format json --output unique_results.json --summary

Deduplication keeps the first normalized DOI; title fallback compares DOI-less records only. Review title matches manually and enrich from raw duplicates; the script does not choose the most complete metadata or link all reports of a study. Unknown years remain for manual review. Ranking only orders the imported sample. Use final BibTeX keys from the export; same-author/year keys receive suffixes. An export timestamp is not the original search date.

Use the official PRISMA guidance and Cochrane selection guidance to keep screening decisions and report/study links auditable.

Raw lines 152 to 183
Runs code python scripts/search_databases.py :170