Giter Club home page Giter Club logo

mongoist's Introduction

mongoist

A node.js module for mongodb built with async/await in mind, that emulates the official mongodb API as much as possible.

Mongoist driver is heavily inspired by mongojs.

Node.js CI Coverage Status

Motivation

The official MongoDB driver for Node.js (https://github.com/mongodb/node-mongodb-native) leaves connection management to the user - this means to connect to a mongodb database this boilerplate code is needed

const { MongoClient } = require('mongodb');

MongoClient
  .connect('mongodb://localhost:27017/myproject')
  .then(connection => {

    connection.close();
  });

Due to the asynchronous nature of connect, a connection that is used everywhere in an application is not that easy to export from a module.

const { MongoClient } = require('mongodb');

MongoClient
  .connect('mongodb://localhost:27017/myproject')
  .then(connection => {

    // THIS WILL NOT WORK AS EXPECTED!!!
    module.exports = connection;
  });

Mongoist solves this problem by managing the connection internally in a lazy fashion. With mongoist you can create a db.js module exporting a not yet opened database connection:

module.exports = mongoist(connectionString);

Along these same lines, connection information may not be available synchronously. The connection information provided to mongoist can be contained in a Promise, affording for gathering the connection information from arbitrary sources (e.g. mongo-memory-server):

module.exports = mongoist(Promise.resolve());

Usage

Please note: Any line in the examples that uses the await keyword should be called inside an async function. If you haven't used async/await yet, you'll want to do some research to help you understand how it works. Or take a look at https://ponyfoo.com/articles/understanding-javascript-async-await for a great read about async/await

Connecting

const mongoist = require('mongoist');
const db = mongoist(connectionString, connectionOptions)

The connectionString and connectionOptions are passed to the underlying official mongodb driver. Find out more about connection strings and options.

Migrating from mongojs

While mongojs uses callbacks only, mongoist uses promises only. To allow migrating to mongoist without migrating the whole application, mongoist supports wrapping the mongojs driver.

const mongojsDb = mongojs(connectionString);
const db = mongoist(mongojsDb);

async function findDocuments() {
  const docs = await db.a.find({});
  // ...
}

// We need to call the async function this way since top level await keyword is not allowed in JavaScript
findDocuments().then(() => console.log('Done querying mongodb'));

Connection Management

Mongoist uses the connection pool provided by the official mongodb driver, so there is no need to manage connections on your own. For most use cases it's best to create a db.js node module that exports a mongoist database connection.

module.exports = mongoist(connectionString);

Accessing Collections

Mongoist uses a proxy implementation under the hood to allow accessing a collection named foo as

db.foo.find(...);

instead of

db.collection('foo').find(...);

Examples

// find everything in mycollection returned as array
const documents = await db.mycollection.find();

// find everything in mycollection returned as a Cursor (no intermediate Promise)
const documentsCursor = db.mycollection.findAsCursor();

// take the first document from the cursor
const document = await documentsCursor.next();

// find everything in mycollection, but sort by name
const sortedDocuments = await db.mycollection.findAsCursor().sort({name: 1}).toArray();

// find a document using a native ObjectId
const documentById = await db.mycollection.findOne({ _id: mongoist.ObjectId('523209c4561c640000000001') });

// Update all documents named 'mathias' and increment their level
const resultUpdate = await db.mycollection.update({name: 'mathias'}, {$inc: {level: 1}}, {multi: true});

// find one named 'mathias', tag him as a contributor and return the modified doc
const resultFindAndModify = await db.mycollection.findAndModify({
  query: { name: 'mathias' },
  update: { $set: { tag: 'maintainer' } },
  new: true
});

// use the save function to just save a document
const doc = await db.mycollection.save({created: 'just now'});

Cursor Operations

The mongodb operations find and aggregate return a cursor, that is resolved in the mongodb shell to an array. Mongoist provides the operations findAsCursor and aggregateAsCursor to return a cursor, and shorthand functions find and aggregate to return an array.

Bulk updates

var bulk = db.a.initializeOrderedBulkOp()
bulk.find({type: 'water'}).update({$set: {level: 1}})
bulk.find({type: 'water'}).update({$inc: {level: 2}})
bulk.insert({name: 'Spearow', type: 'flying'})
bulk.insert({name: 'Pidgeotto', type: 'flying'})
bulk.insert({name: 'Charmeleon', type: 'fire'})
bulk.find({type: 'flying'}).removeOne()
bulk.find({type: 'fire'}).remove()
bulk.find({type: 'water'}).updateOne({$set: {hp: 100}})

await bulk.execute();
// done...

Events

const db = mongoist('mongodb://localhost/mydb')

// Emitted if no db connection could be established
db.on('error', function (err) {
  console.log('database error', err)
});

// Emitted if a db connection was established
db.on('connect', function () {
  console.log('database connected')
})

Database commands

With mongoist you can run database commands just like with the mongo shell using db.runCommand()

const result = await db.runCommand({ping: 1});
console.log('we\'re up');

or db.collection.runCommand()

const result = await db.things.runCommand('count');
console.log(result);

Similarly, you can use db.adminCommand() to run a command on the admin database of the MongoDB cluster or instance you're connected to:

const result = await db.adminCommand({currentOp: 1});
console.log(result);

Replication Sets

Mongoist can connect to a mongo replication set by providing a connection string with multiple hosts

const db = mongoist('rs-1.com,rs-2.com,rs-3.com/mydb?slaveOk=true');

For more detailed information about replica sets see the mongo replication docs

API

This API documentation is a work in progress.

Exposed Prototypes

Mongoist exposes the prototypes of Database, Collection, Cursor and Bulk to provide basic support for mocking, stubbing data access in tests.

const mongoist = require('mongoist');

// Override collection find behavior to always return { foo: 'bar' }
mongoist.Collection.prototype.find = function() {
  return [
    { foo: 'bar' }
  ]
}

const db = mongoist('test');
console.log(db.a.find({}));

// Will print out [{ foo: 'bar' }]

Collection

All operations return promises. If a return type is given, this is the type of the resolved promise.

db.collection.aggregate(pipelineArray, [options])

See https://docs.mongodb.org/manual/reference/method/db.collection.aggregate/

db.collection.aggregateAsCursor(pipelineArray, [options])

Returns a cursor instead of an array as db.collection.aggregate does.

See https://docs.mongodb.org/manual/reference/method/db.collection.aggregate/

db.collection.count([query], [options])

Supported options:

Field Type Description
limit integer Optional. The maximum number of documents to count.
skip integer Optional. The number of documents to skip before counting.
hint string or document Optional. An index name hint or specification for the query.
maxTimeMS integer Optional. The maximum amount of time to allow the query to run.
collation document Optional.

See https://docs.mongodb.org/manual/reference/method/db.collection.count/

db.collection.createIndex(keys, options)

See https://docs.mongodb.org/manual/reference/method/db.collection.createIndex/

db.collection.distinct(field, query)

See https://docs.mongodb.org/manual/reference/method/db.collection.distinct/

db.collection.drop()

See https://docs.mongodb.org/manual/reference/method/db.collection.drop/

db.collection.dropIndex(index)

See https://docs.mongodb.org/manual/reference/method/db.collection.dropIndex/

db.collection.dropIndexes()

See https://docs.mongodb.org/manual/reference/method/db.collection.dropIndexes/

db.collection.ensureIndex(keys, options)

See https://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/

Deprecation Notice: Deprecated since version 3.0.0: db.collection.ensureIndex() is now an alias for db.collection.createIndex().

db.collection.find([query], [projection])

Returns an array of documents.

See https://docs.mongodb.org/manual/reference/method/db.collection.find/

db.collection.findAsCursor([query], [projection])

Returns a cursor instead of an array as db.collection.find does.

See https://docs.mongodb.org/manual/reference/method/db.collection.find/

db.collection.findOne([query], [projection])

Apply a query and returns one single document.

See https://docs.mongodb.org/manual/reference/method/db.collection.findOne/

db.collection.findAndModify(document)

See https://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/

db.collection.getIndexes()

See https://docs.mongodb.org/manual/reference/method/db.collection.getIndexes/

db.collection.group(document)

See https://docs.mongodb.org/manual/reference/method/db.collection.group/

Deprecation Notice: Deprecated since version 3.4: Mongodb 3.4 deprecates the db.collection.group() method. Use db.collection.aggregate() with the $group stage or db.collection.mapReduce() instead.

db.collection.insert(docOrDocs, options)

See https://docs.mongodb.com/manual/reference/method/db.collection.insert/

db.collection.isCapped()

See https://docs.mongodb.com/manual/reference/method/db.collection.isCapped/

db.collection.mapReduce(map, reduce, options)

See https://docs.mongodb.com/manual/reference/method/db.collection.mapReduce/

db.collection.reIndex()

See https://docs.mongodb.com/manual/reference/method/db.collection.reIndex/

db.collection.remove(query, [justOne])

Equivalent to db.collection.remove(query, { justOne: true/false })

See https://docs.mongodb.com/manual/reference/method/db.collection.remove/

db.collection.remove(query, [options])

See https://docs.mongodb.com/manual/reference/method/db.collection.remove/

db.collection.replaceOne(filter, replacement, [options])

See https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/

db.collection.runCommand(command)

See https://docs.mongodb.com/manual/reference/method/db.collection.runCommand/

db.collection.save(doc, [options])

See https://docs.mongodb.com/manual/reference/method/db.collection.save/

db.collection.stats()

See https://docs.mongodb.com/manual/reference/method/db.collection.stats/

db.collection.update(query, update, [options])

See https://docs.mongodb.com/manual/reference/method/db.collection.update/

db.collection.initializeOrderedBulkOp([options])

Creates a new ordered bulk. This operation is sync so no await is needed. See the Bulk section for more details.

db.collection.initializeUnorderedBulkOp([options])

Creates a new unordered bulk. This operation is sync so no await is needed. See the Bulk section for more details.

db.collection.toString()

Get the name of the collection.

Cursor

Cursor implements a readable stream. For example, you can pipe a cursor to a writeable stream.

db.someCollection.findAsCursor()
  .pipe(writeableStream)
  .on('finish', () => {
    console.log('all documents piped to writeableStream');
  });

cursor.addCursorFlag(flag, value)

See https://mongodb.github.io/node-mongodb-native/3.1/api/Cursor.html#addCursorFlag

cursor.batchSize(size)

See https://docs.mongodb.com/manual/reference/method/cursor.batchSize/

cursor.collation(collationDocument)

See https://docs.mongodb.com/manual/reference/method/cursor.collation/

Only supported with MongoDB 3.4 or higher.

cursor.count()

See https://docs.mongodb.com/manual/reference/method/cursor.count/

cursor.explain()

See https://docs.mongodb.com/manual/reference/method/cursor.explain/

cursor.limit(n)

See https://docs.mongodb.com/manual/reference/method/cursor.limit/

cursor.next()

See https://docs.mongodb.com/manual/reference/method/cursor.next/

cursor.hasNext()

See https://docs.mongodb.com/manual/reference/method/cursor.hasNext/

cursor.forEach(fn)

See https://docs.mongodb.com/manual/reference/method/cursor.foreach/

cursor.map(fn)

See https://docs.mongodb.com/manual/reference/method/cursor.map/

cursor.rewind()

Rewinds a cursor.

cursor.skip(n)

See https://docs.mongodb.com/manual/reference/method/cursor.skip/

cursor.sort(sortOptions)

See https://docs.mongodb.com/manual/reference/method/cursor.sort/

cursor.toArray()

See https://docs.mongodb.com/manual/reference/method/cursor.toArray/

cursor.close() (alias cursor.destroy())

https://docs.mongodb.com/manual/reference/method/cursor.close/

Database

db.createUser(document)

See https://docs.mongodb.com/manual/reference/method/db.createUser/

db.dropUser(username)

See https://docs.mongodb.com/manual/reference/method/db.dropUser/

db.dropAllUsers()

See https://docs.mongodb.com/manual/reference/method/db.dropAllUsers/

db.createCollection(name, options)

See https://docs.mongodb.com/manual/reference/method/db.createCollection/

db.getCollectionNames()

See https://docs.mongodb.com/manual/reference/method/db.getCollectionNames/

db.getCollectionInfos() (alias db.listCollections())

See https://docs.mongodb.com/manual/reference/method/db.getCollectionInfos/

db.getLastError()

See https://docs.mongodb.com/manual/reference/method/db.getLastError/

db.getLastErrorObj()

See https://docs.mongodb.com/manual/reference/method/db.getLastErrorObj/

db.runCommand(command)

See https://docs.mongodb.com/manual/reference/method/db.runCommand/

db.adminCommand(command)

See https://mongodb.github.io/node-mongodb-native/3.3/api/Db.html#executeDbAdminCommand

db.stats()

See https://docs.mongodb.com/manual/reference/method/db.stats/

db.close()

See https://docs.mongodb.com/manual/reference/method/db.close/

db.dropDatabase()

See https://docs.mongodb.com/manual/reference/method/db.dropDatabase/

Bulk

bulk.execute()

Executes a bulk.

See https://docs.mongodb.com/manual/reference/method/Bulk.execute/

bulk.find(query)

See https://docs.mongodb.com/manual/reference/method/Bulk.find/

bulk.find.remove()

See https://docs.mongodb.com/manual/reference/method/Bulk.find.remove/

bulk.find.removeOne()

See https://docs.mongodb.com/manual/reference/method/Bulk.find.removeOne/

bulk.find.replaceOne(document)

See https://docs.mongodb.com/manual/reference/method/Bulk.find.replaceOne/

bulk.find.update(updaterParam)

See https://docs.mongodb.com/manual/reference/method/Bulk.find.update/

bulk.find.updateOne(updaterParam)

See https://docs.mongodb.com/manual/reference/method/Bulk.find.updateOne/

bulk.find.upsert(upsertParam)

See https://docs.mongodb.com/manual/reference/method/Bulk.find.upsert/

bulk.insert(document)

See https://docs.mongodb.com/manual/reference/method/Bulk.insert/

bulk.toString()

See https://docs.mongodb.com/manual/reference/method/Bulk.toString/

bulk.tojson()

See https://docs.mongodb.com/manual/reference/method/Bulk.tojson/

mongoist's People

Contributors

adborroto avatar bradvogel avatar christophwalcher avatar chuanyuwang avatar dependabot[bot] avatar devsnowy avatar dnechay avatar gillesdemey avatar jsalvata avatar lindakatcodes avatar raphaelbs avatar saintedlama avatar semantic-release-bot avatar shils avatar skeggse avatar ttacon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongoist's Issues

Removal of `update` function introduced functional regression

In #21, the update function was changed to map to either updateOne or updateMany. In that PR it was mentioned that update was deprecated which was the motivating factor behind the patch. However, as part of this fix we need to add support for replaceOne on the normal collection interface as the change introduced a functional regression. Consider the case when you actually do want to fully replace every field in an object via an update call - that will now fail as updateOne and updateMany require atomic operators. Let me know your thoughts on this, I'll try to get together a quick patch for this later today.

Run tests on Node 6 and 7

Follow-up to #3.

The tests use async/await so this would involve transpiling them and switching between the transpiled and untranspiled versions at runtime.

How to declare mongoist in a module - ES6 style?

I used to declare the database connection like this in a module in the commonJS fashion:

const mongoist = require('mongoist'); 
const conn="mongodb://localhost:27017/data"; 
const options="";
module.exports = mongoist(conn,options);

Now, I can't make it work using ES6 as the following code does not work:

import * as mongoist from "mongoist"
const conn="mongodb://localhost:27017/data"; 
const options="";
export mongoist(conn,options);
On the import side, I use:

import * as db from "./db.mjs"


For sure, i could write "export {mongoist, conn, options};"

but then, in the main tread the following does not work: db.mongoist(db.conn,db.options)

i get the error

TypeError: db.mongoist is not a function
at file:///home/bit/test.js:3:13
at ModuleJob.run (node:internal/modules/esm/module_job:175:25)
at async Loader.import (node:internal/modules/esm/loader:178:24)
at async Object.loadESM (node:internal/process/esm_loader:68:5)

Breaking API change from 1.5.1 to 1.6.0

Taking a look at the recent API changes, it looks like a breaking change was introduced between versions 1.5.1 and 1.6.0. Previously you could use mongoist with a existing mongojs>=1.4.1 connections since they both expect [email protected] connections under the hood. However, version 1.6 instead expects [email protected] connections along with its breaking changes to the find and findOne api. This means that [email protected] no longer supports mongojs connections due to mongodb's breaking API changes.

As a solution, it'd be great to include information about the breaking change in the changelog and publish v2.0 of the module. Alternatively we could find a way to distinguish between 2.X and 3.X mongodb drivers.

Transactions

There is a way to perform a transaction between two collections using mongoist?

[Feature request] Consideration for altering constraints in `Database::connect()`

Hi there - fantastic project!

I was wondering what your opinion was on relaxing the check to detect prior mongoist connections? In particular, this check will fail if the mongoist reference that is passed in is a mongoist reference where the module was loaded separately. This can happen either due to version differences, multiple linked packages during testing, or any other situation where mongoist isn't flattened to a single module under a package's node_modules. In this situation, the failure to detect the reference as a Database reference means that we'll return undefined even though we had a valid connection that we could have used to make a new connection from.

It's most likely too dangerous to reuse the connection if it was loaded via a different instance of the mongoist package as we can't be sure of API uniformity, but what do you think about using the passed in mongoist reference in order to synthesize a new mongoist reference?

[Bug] Mongoist does not open new connection after close

I have created db.js module with code

//db.js
module.exports = mongoist('test');

Now I use db.js module within my tests in the following way

//foobar.spec.js
const db = require('./db');

describe('foo', () => {
  beforeEach(() => db.connect());
  afterEach(() => db.close());

  it('is some test', async () => {
    expect(await db.mycol.find({_id: 'foo'})).toBeNull();
  });

  it('is some other test', async () => {
    expect(await db.mycol.find({_id: 'bar'})).toBeNull();
  });
});

The second test will fall with an error MongoError: topology was destroyed because the connection will be closed after first test but not be opened anew before second test.

It is happen because Database#connect method always try to return the old connection even if it was be closed.

I think we should set this.connection to equal null within Database#close method about like this

return this.client
  .close(force)
  .then(() => this.connection = null)
  .catch((e) => {
  // Ignore this
    debug(`Could not close the connection due to error "${e.message}" ${e.stack}`);
  });

TypeScript definitions

Would be nice to have a typescript definition this project, as i bet many want to use it.
I believe there are ways to autogenerate most of it but probably need some touchups after.

fairly new to mongodb in nodejs but from what ive seen, i don't really want to deal with connection handeling etc which makes this project a great candiate, but our linter rules does not allow for required.

Proposal to archive this package.

As of version 5.0.0, the official mongo nodejs driver supports only promises. Given that the original purpose of this library was to add a promise-compatible interface for the native driver, I think mongoist is no longer useful. Anyone who'd like a promise-compatible api, should just use the native driver.

As a result, I'm proposing adding a notice to the readme and archiving this repo. As it is, the package is pretty out of date and no longer really useful for modern node/mongodb projects.

Documentaion error

you have a typo in your documentation

const result = await db.things.runCommand('count');
console.log(result);
})

the }) should not be there!

Consider relaxing engine requirement

Hi, thanks for this package! Does this package strictly require Node 8.4, or would you consider relaxing the engine requirement? async/await support was added in Node 7.6.0 (hover over 7.10.1 at top here to see).

It's even possible to use async/await even in Node 6 if you use transpilation—though typically packages don't transpile their dependencies, so, since this package internally uses async/await, supporting the latter would require this package transpile itself before publishing. We would be glad to add support for that if you would consider it. In our own packages we are readying for the upgrade to Node 8 by transpiling pre-publish and switching between the transpiled and untranspiled versions at runtime, using a shim like

// index.js
// This file was created by a script of ours that we would be glad to publish.
// We have an automatic way of removing the shim when transpilation is no longer required too.
const semver = require('semver');

let main;
if (semver.lt(process.version, '7.6.0')) {
  main = require('./dist/node/index.js');
} else {
  main = require('./src/node/index.js');
}
module.exports = main;

SyntaxError in readme

await keyword can only appear inside an async function, not like it's presented in sections: mongojs, examples, bulk and database commands.

Solutions:

  • Wrap code in an aiife (async iife): (async () => { /* fn body */ }())
  • Add a comment: // inside async function
  • Or an even better solution

As not to cause confusion for those it isn't obvious to ;)

Encryption

I am very much interested in adding encryption to my MongoDB database and I was wondering if there was a way for me to easily do so with mongoist.

EDIT: Even exposing a concept like setters/getters would work for me.

Export flow types

We use flow types a lot, and are in the process of writing flow types for mongoist. I intend to publish these in flow-typed, but am wondering if @saintedlama has any interest in including those types either in this package (separate from the code), or using flow in the implementation itself. It seems that typescript may be a more broadly supported tool these days, though.

I'll resolve this either way, but the result may be a new PR against flow-typed.

[Bug] mongodb+srv:// connection string

mongoist: 1.7.4

When passing the connection string to the underlying mongodb driver, mongoist prepends a "mongodb://" to the connection string when a "mongodb+srv://" connection string is used.

That is, mongodb+srv://server.example.com/ is changed to mongodb://mongodb+srv://server.example.com/ and then passed to the mongodb driver, leading to the following error:

Error: Username contains an illegal unescaped character
at parseConnectionString ( .../node_modules/mongodb/lib/url_parser.js:315:11)
at parseHandler ( .../node_modules/mongodb/lib/url_parser.js:146:14)
at module.exports ( .../node_modules/mongodb/lib/url_parser.js:28:12)
at Promise ( .../node_modules/mongoist/lib/database.js:188:5)
at new Promise ()
at parseUrl ( .../node_modules/mongoist/lib/database.js:187:10)
at Database.connect ( .../node_modules/mongoist/lib/database.js:101:14)
at Collection.connect ( .../node_modules/mongoist/lib/collection.js:18:20)
at Cursor [as cursorFactory] ( .../node_modules/mongoist/lib/collection.js:36:8)
at Cursor.getCursor ( .../node_modules/mongoist/lib/cursor.js:116:8)

witth findAsCursor projection is not used ?

Hi there,

seems there is an issue when using findAsCursor, at least for me I can do what I want, I always get the _id field, same with all other fields I try to exclude.

example :

try { results = await db.issues.findAsCursor( { }, { _id : false, owner : false, }).sort({ reliability : -1, percent : -1, }).toArray(); } catch (error) { throw (error); }

When trying this, and outputting with

if (issues = await getIssues()) { for (let issue of issues) { log (issue);

I get the _id and also owner displayed.

AM I doing something wrong or is there an issue.

best regards

support async iterator protocol on cursors

We do not yet support the async iterator protocol, which would serve to replace a manual loop using next invocations. This covers a slightly separate use-case than forEach as forEach doesn't apply backpressure during cursor processing, and doesn't help understand when all user operations on the cursor have completed if they're async.

The addition of async iterator support could be coupled with adding fn Promise support to the forEach API but that would likely not be backwards-compatible.

Without async iterator support

forEach approach

async function processCursor(cursor) {
  // forEach does not interact with promises returned by each invocation of fn
  await cursor.forEach(async (doc) => {
    await new Promise((resolve) => setTimeout(resolve, 500));
    out.write(doc);
  });

  // Prints ~500ms before the last document finishes processing.
  console.log('all done');
}

With manual iteration

async function processCursor(cursor) {
  for (let doc; doc = await cursor.next(); ) {
    await new Promise((resolve) => setTimeout(resolve, 500));
    out.write(doc);
  }

  // Prints after the last document finishes processing.
  console.log('all done');
}

With async iterator support

async function processCursor(cursor) {
  for await (const doc of cursor) {
    await new Promise((resolve) => setTimeout(resolve, 500));
    out.write(doc);
  }

  // Prints after the last document finishes processing.
  console.log('all done');
}

Prior art

`db.collection.findAsCursor` projection param is ignored

db.collection.findAsCursor projection parameter is ignored in v1.7.0. Looking into the collections.js file shows that you would actually need to call the method as db.collection.findAsCursor({...}, {projection: {...}}) in order to get it processed. I do believe that this does not follow the current documentation, nor is intentional.

Proxy collisions with `Database` class instances

mongoist version: 1.7.2 but I believe this is problem affects older versions.

The problem is that the Database object instance created with mongoist has quite a few instance properties whose name can be somewhat commonly used as collection names, this causes the proxy functionality to break. For example:

this.features - means you cannot reference to a features collection in your database via Proxy.

Besides this one, options, client, connection and domain (this one introduced by extending EventEmitter can probably be considered very plausible collection names.

No support for collations

There is no support for collations.

This means all alphabetical sorting uses binary sort (where 'a' comes after 'Z'). It's bad enough in English, will be unbearable in languages with diacritics ('Á' would come after 'z').

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.