G. Deward
G. Deward

Reputation: 1592

Return Mongo document using Mongoose where subdocument does NOT exist?

Help! I'm losing my mind. I need to simply return a Mongo document, using Mongoose, IF a sub document does not exist.

My schemas:

var userSchema = new mongoose.Schema({
    email: {type: String, unique: true, lowercase: true},
    password: {type: String, select: false},
    displayName: String,
    picture: String,
    facebook: String,
    deactivation: deactiveSchema
});

var deactiveSchema = new mongoose.Schema({
    when : { type: Date, default: Date.now, required: true },
    who  : { type: Schema.Types.ObjectId, required: true, ref: 'User' }
});

My goal is to lookup a user by their facebook ID if they have not been deactivated.

If they have been deactivated, then a deactivation subdocument will exist. Of course, to save space, if they are active then a deactivation will not exist.

On a side note, I'm also worried about how to properly construct the index on this logic.

I'd post snippets but every attempt has been wrong. =(

Upvotes: 1

Views: 750

Answers (3)

chriskelly
chriskelly

Reputation: 7736

Mongoose has many options for defining queries with conditions and a couple of styles for writing queries:

Condition object

var id = "somefacebookid";

var condition = {
  facebook : id, 
  deactivation: { $exists : true}
};

user.findOne(condition, function (e, doc) {
     // if not e, do something with doc
}) 

http://mongoosejs.com/docs/queries.html

Query builder

Alternatively, you may want to use the query builder syntax if you are looking for something closer to SQL. e.g.:

var id = "somefacebookid"; 
users
    .find({ facebook : id }).
    .where('deactivation').exists(false)
    .limit(1)
    .exec(callback);

Upvotes: 0

chrisbajorin
chrisbajorin

Reputation: 6153

Since you are retiring data and not deleting, I'd go with one of two approaches:

Flag for retired (Recommended)

add to your schema:

retired: {
    type: Boolean,
    required: true
}

and add an index for this query:

userSchema.index({facebook: 1, retired: 1})

and query:

User.find({facebook: facebookId, retired: false}, callback)

Query for existence

User.find().exists("deactivation", false).exec(callback)

The latter will be slower, but if you really don't want to change anything, it will work. I'd recommend taking some time to read through the indexing section of the mongo docs.

Upvotes: 1

Alvaro Silvino
Alvaro Silvino

Reputation: 9763

You can use $exists operator:

 userSchema.find({deactivation:{$exists:false}}).exec(function(err,document){


  });

or $ne:

 userSchema.find({deactivation:{$ne:null}}).exec(function(err,document){


  });

Upvotes: 1

Related Questions