firestore-pagination
how to install
npm install @samwen/firestore-pagination --save
how to use
You will need generate private key under service accounts and save it as serviceAccount.json in the project root folder.
You can use the import-json.js to import books.json into your firestore database.
node import-json.js books.json
Copy/paste config file as config.js.
demo.js
const admin = require('firebase-admin');
const ConfigUtil = require('@samwen/config-util');
const { Pagination } = require('@samwen/firestore-pagination');
const serviceAccount = require('../serviceAccount.json');
admin.initializeApp({ credential: admin.credential.cert(serviceAccount) });
const db = admin.firestore();
const config = new ConfigUtil(require('./config.js'));
(async () => {
let batch_key = null, action = null;
if (process.argv.length > 2) {
batch_key = process.argv[2];
}
if (process.argv.length > 3) {
action = process.argv[3];
}
const options = {
batch_key: batch_key,
select: ['id', 'isbn', 'title'],
filters: [
['publishedDate.date', 'order-by', 'desc'],
['publishedDate.date', '>=', '2010-01-01'],
],
nodb_filters: [
['id', '!=', '00346'],
['isbn', '!=', '161729084X'],
]
};
let pages = new Pagination(db, config);
const result = await pages.do_preview(options);
console.log('\n*** preview result: ' + JSON.stringify(result));
console.log('metrics: ' + JSON.stringify(pages.get_metrics())+'\n');
pages = new Pagination(db, config);
const batch_pages = await pages.do_paging(action, options);
if (batch_pages) {
pages.print_batch_pages(batch_pages, options.select);
console.log();
if (batch_pages.has_prev) {
console.log('for previous batch: \tnode demo.js ' + batch_pages.batch_key + ' PREV')
}
console.log('for current batch: \tnode demo.js ' + batch_pages.batch_key)
if (batch_pages.has_next) {
console.log('for next batch: \tnode demo.js ' + batch_pages.batch_key + ' NEXT')
}
} else {
console.log('no data to list');
}
})();
- There are 3 examples under examples folders: demo.js, interactive.js and get-batch.js.
$ node demo.js
*** preview result: {"total":"> 100","cached_count":81}
metrics: {"read_docs":1,"write_docs":1,"delete_docs":0,"runtime":518}---------------------- batch no: 1 ----------------------
### page no 1
id, isbn, title
1: 00368, 1617291692, The Well-Grounded Rubyist, Second Edition
2: 00352, 1617291455, Ember.js in Action
3: 00349, 1617291412, The Joy of Clojure, Second Edition
4: 00289, 1617290629, CoffeeScript in Action
5: 00387, 1617292133, Learn SQL Server Administration in a Month of Lunches
### page no 2
id, isbn, title
1: 00186, 1935182994, EJB 3 in Action, Second Edition
2: 00350, 1617291420, iOS 7 in Action
3: 00358, 1617291560, Practical Data Science with R
4: 00324, 1617291021, Solr in Action
5: 00305, 1617290904, Play for Java
### page no 3
id, isbn, title
1: 00336, 1617291218, The Mikado Method
2: 00323, 1617291056, Kanban in Action
3: 00302, 1617290823, Mule in Action, Second Edition
4: 00341, 1617291307, Gradle in Action
5: 00291, 1617290491, HTML5 in Action
### page no 4
id, isbn, title
1: 00272, 1617290327, Ext JS in Action, Second Edition
2: 00365, 1617291374, Windows Phone 8 in Action
3: 00317, 1617290971, Learn Windows IIS in a Month of Lunches
4: 00301, 1617290394, Linked Data
5: 00306, 1617290920, Hello World! Second Edition
batch_key: 2x7xAh2OteQAorX33uvpYBeGdIZ-2wlXBxTHH4BCypr3FkFASqHbMibqnO
start_page_no: 1 has_prev: false has_next: true
metrics: {"read_docs":1,"write_docs":1,"delete_docs":0,"runtime":372}
for current batch: node demo.js 2x7xAh2OteQAorX33uvpYBeGdIZ-2wlXBxTHH4BCypr3FkFASqHbMibqnO
for next batch: node demo.js 2x7xAh2OteQAorX33uvpYBeGdIZ-2wlXBxTHH4BCypr3FkFASqHbMibqnO NEXT
$ node interactive.js
cleanup items: 0
metrics: {"read_docs":1,"write_docs":0,"delete_docs":0,"runtime":484}
---------------------- batch no: 1 ----------------------
### page no 1
id, pages, date, isbn, title
1: 00035, 350, 2012-02-13, 1935182080, Hello! Python
2: 00089, 300, 2012-02-13, 1933988754, SharePoint 2010 Site Owner's Manual
3: 00266, 325, 2012-02-24, 1933988770, C++ Concurrency in Action
4: 00200, 0, 2012-04-04, 1617290181, Machine Learning in Action
5: 00142, 0, 2012-04-11, 1935182498, MacRuby in Action
### page no 2
id, pages, date, isbn, title
1: 00064, 500, 2012-04-13, 193518296X, Spring Roo in Action
2: 00257, 0, 2012-04-20, 1935182978, RabbitMQ in Action
3: 00234, 0, 2012-04-30, 1617290114, PowerShell and WMI
4: 00244, 0, 2012-05-14, 1935182706, Scala in Depth
5: 00184, 450, 2012-05-25, 1617290416, ASP.NET MVC 4 in Action
### page no 3
id, pages, date, isbn, title
1: 00295, 0, 2012-05-30, 1617290610, Flex Mobile in Action
2: 00193, 925, 2012-06-01, 1617290319, Silverlight 5 in Action
3: 00009, 375, 2012-06-04, 1935182234, Griffon in Action
4: 00404, 0, 2012-07-10, 1617290068, The Well-Grounded Java Developer
5: 00204, 0, 2012-07-12, 1617290122, Activiti in Action
### page no 4
id, pages, date, isbn, title
1: 00065, 0, 2012-07-27, 1617290270, SOA Governance in Action
2: 00196, 0, 2012-08-21, 1617290092, Windows Phone 7 in Action
3: 00220, 250, 2012-09-12, 1933988266, SOA Patterns
4: 00311, 0, 2012-09-14, 1617290777, Programming the TI-83 Plus/TI-84 Plus
5: 00411, 400, 2012-09-19, 1935182439, Spring Integration in Actionbatch_key: 9SVCj9yVtNQz9XhHyAvmBLe96jA-2wlXBxTHOTwmCC5ZKspLzfl06Nkbo8
start_page_no: 1 has_prev: false has_next: true
metrics: {"read_docs":1,"write_docs":1,"delete_docs":0,"runtime":382}
*** preview result: {"total":78,"cached_count":78}
metrics: {"read_docs":1,"write_docs":1,"delete_docs":0,"runtime":338}
Q Quit
C Redo current pages (default)
P Show previous pages
N Show next pages
$ node get-batch.js 9SVCj9yVtNQz9XhHyAvmBLe96jA 2
---------------------- batch no: 2 ----------------------
### page no 5
id, pageCount, isbn, title
1: 00148, 450, 193518234X, Restlet in Action
2: 00293, 0, 1617290238, Hadoop in Practice
3: 00056, 325, 1935182897, Hello! HTML5 & CSS3
4: 00294, 0, 1617290521, HBase in Action
5: 00329, 0, 1617291080, Learn Windows PowerShell in a Month of Lunches, ...
### page no 6
id, pageCount, isbn, title
1: 00296, 0, 1617290432, HTML5 for .NET Developers
2: 00331, 0, 1617291161, Learn PowerShell Toolmaking in a Month of Lunches
3: 00212, 300, 193398869X, Secrets of the JavaScript Ninja
4: 00098, 0, 1617290262, Metaprogramming in .NET
5: 00106, 350, 193398838X, Taming Text
### page no 7
id, pageCount, isbn, title
1: 00307, 0, 1617290866, Dart in Action
2: 00247, 0, 1935182846, GWT in Action, Second Edition
3: 00125, 350, 1935182579, Effective Unit Testing
4: 00298, 0, 1617290556, PowerShell in Depth
5: 00276, 0, 1617290548, Third-Party JavaScript
### page no 8
id, pageCount, isbn, title
1: 00322, 0, 1617291048, OCA Java SE 7 Programmer I Certification Guide
2: 00209, 0, 1935182757, Scala in Action
3: 00262, 600, 1935182056, Spring in Practice
4: 00274, 300, 1617290246, Arduino in Action
5: 00297, 0, 1617290564, 50 Android Hacksbatch_key: 9SVCj9yVtNQz9XhHyAvmBLe96jA-2r7nSAPOpSKJWv8EpruMm9jAmJekWghiMSF8gs
start_page_no: 5 has_prev: true has_next: true
metrics: {"read_docs":1,"write_docs":1,"delete_docs":0,"runtime":511}
config file
'use strict';
const config = {
collection_name: 'books', // the collection name the pagination is running
appendix: '_metadata', // appendix for the collection name that store cached results
default_sort_field: 'id', // will be used if no order-by is provided in the flter
default_sort_order: 'asc',
max_sorted_fields: 1, // more than 1 will need to setup composite index ahead
page_size: 5, // items per page
batch_size: 4, // pages per batch
cache_version: 1, // cache version
cache_preview: true, // cache the result of preview
cache_pages: true, // cache batch pages
max_pre_cached_batches: 3, // pre cache batch pages during preview
preview_cache_ttl: 3600 * 2, // time to live for preview cache
page_cache_ttl: 1800, // time to live for batch pages cache
cleanup_timeout: 3600 * 4, // when to clean up caches
max_docs_limit: 100, // if more than max_docs_limit, it shows the total as > max_docs_limit
max_cached_ids: 80, // the max ids will be cached during preview
promises_size: 256, // promises size
read_multiply: 2, // when we have nodb filers, control how many additional docs to read
}
module.exports = config;