Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot xor mongodb field from nodejs without mongoose

I'm trying to xor the field status, in a document such as this:

{
    "_id" : ObjectId("58c51e1aedb6e4000410ddbf"),
    "query" : "developer",
    "user_id" : "1413322622039651",
    "status" : 1,
    "links" : [
        "840673302343483394",
        "840672745222483968",
        "840672580717686785",
        "840672427550089216",
        "840582170548850688",
        "840581988918669312"
    ],
    "links_size" : 6,
    "created" : ISODate("2017-03-12T10:08:26.369Z")
}

I'm using this code:

var args = {'_id': new ObjectID(queryId)};
var bit = {$bit: {'status': {xor: 1}}};
db.collection('query').update(args, bit, function(err, result) {});

The query produces no error but the field status is not changed. I think that the problem is that it interprets 1 as a double not as a integer. I tried: parseInt(1) but it also had no effect. I tried to use NumberInt(1) but got the error NumberInt is not defined.

So I can't make it work in my code; however, the equivalent query through the mongo shell works as expected:

db.query.update(
  {"_id":ObjectId("58c3b98e458f0700045b1846")}, 
  {"$bit":{"status":{"xor":NumberInt(1)}}}
)

I googled and found that NumberInt is present in the mongoose-int32 package but it requires mongoose. I don't want to add mongoose as a dependency for my project so I'm looking for another solution.

like image 613
rocknow Avatar asked Mar 11 '17 09:03

rocknow


People also ask

Do you need Mongoose for MongoDB?

Mongoose is an object document modeling (ODM) layer that sits on top of Node's MongoDB driver. If your coming from SQL, it's similar to an ORM for a relational database. While it's not required to use Mongoose with the Mongo, here are four reasons why using Mongoose with MongoDB is generally a good idea.

Should I learn mongoose or MongoDB?

On the downside, learning mongoose can take some time, and has some limitations in handling schemas that are quite complex. However, if your collection schema is unpredictable, or you want a Mongo-shell like experience inside Node. js, then go ahead and use the mongodb driver. It is the simplest to pick up.

Is Mongoose ODM or ORM?

Mongoose is an ODM that provides a straightforward and schema-based solution to model your application data on top of MongoDB's native drivers.


1 Answers

The problem comes from the status field type stored in your document

here it is

{ "status" : 1, ... }

but you should have this:

{ "status" : NumberLong(1), ... }

First, convert all status field to NumberLong using this code (run it directly in the shell)

db.query.find().forEach( function(obj) {
    obj.status = new NumberLong(obj.status);
    db.query.save(obj);
});

then just update your previous code like this :

const MongoClient = require('mongodb').MongoClient
const ObjectId = require('mongodb').ObjectId
const Long = require('mongodb').Long

MongoClient.connect('mongodb://localhost:27017/database', function (err, db) {
  if (err != null) {
    console.log(err)
  } else {
    let args = {'_id': new ObjectId('58c64231b13b6239d9e496da')}
    let bit = {$bit: {'status': {xor: Long.fromInt(1)}}}

    db.collection('query').update(args, bit, function (err, result) {
      if (err != null) {
        console.error(err)
      }
      db.close()
    })
  }
})

This worked using:

  • node v7.3.0
  • npm package mongodb 2.2.24
  • MongoDB 3.4.1
like image 126
felix Avatar answered Nov 10 '22 06:11

felix