bevacqua
bevacqua

Reputation: 48496

mongoose query subdocument or empty

I have the following model

var schema = new Schema({
    type: String,
    accounts: [{ type: ObjectId, ref: "Account", index: 1 }],
    accountTypes: [String],
    headline: String,
    contents: String,
    date: { type: Date, "default": Date.now }
});

I need a query which based on an account, gives me all document which match one of these.

What's the best way to perform this query in as few steps as possible? Can I do this in a single query? How?

I know I can pile these queries on top of each other, but it doesn't feel very performant.

Here's what I have so far, but I'm not sure if it'd work.

Notification.find({
    $or: [
        { $and: [{ $where: "this.accounts.length === 0" }, { $where: "this.accountTypes.length === 0" }] },
        { $and: [{ $where: "this.accounts.length === 0" }, { accountTypes: account.type }] },
        { $and: [{ $where: "this.accountTypes.length === 0" }, { accounts: account._id }] }
    ]
}, function (err, notifications) {
    // stuff
});

Upvotes: 0

Views: 1036

Answers (1)

heinob
heinob

Reputation: 19474

Try this:

Notification.find({
    $or: [
        { $and: [{ accounts: { $size: 0 }, { accountTypes: {$size: 0 }] },
        { $and: [{ accounts: { $size: 0 }, { accountTypes: account.type }] },
        { $and: [{ accountTypes: { $size: 0 }, { accounts: account._id }] }
    ]
}, function (err, notifications) {
    // stuff
});

EDIT:

or even shorter (thanks to JohnnyHK for the hint)

Notification.find({
    $or: [
        { accounts: { $size: 0 }, accountTypes: { $size: 0 } },
        { accounts: { $size: 0 }, accountTypes: account.type },
        { accountTypes: { $size: 0 }, accounts: account._id }
    ]
}, function (err, notifications) {
    // stuff
});

Upvotes: 4

Related Questions