Moro Silverio
Moro Silverio

Reputation: 97

What is wrong with this mongo $or query

This query works perfectly

{
$or:[{author:this.userId} , {somethingelse:true} ]
}

But when I try:

{
$or:[{author:this.userId} , {sharedwith[this.userId]:true} ]
}

I receive the message

Errors prevented startup:
While processing files with ecmascript (for target os.linux.x86_64): server/main.js:113:43: Unexpected token, expected , (113:43)

=> Your application has errors. Waiting for file change.

And thats where the comma , in the $or statement is

Help

Upvotes: 0

Views: 115

Answers (2)

ghybs
ghybs

Reputation: 53215

I guess that you are trying to retrieve all documents for which the current user is the author, or which have been shared with him/her? And therefore that you have structured your documents with a sharedWith field which is a hash map of userId as keys and boolean as value?

Document structure:

{
    author: string,
    sharedWith: {
        <userId1>: boolean
        // <userId2>…
    }
}

In that case, your MongoDB query should use the dot notation to specify the value of a nested field within sharedWith field:

{
    $or: [{
        author: string
    }, {
        "sharedWith.<userId>": boolean
    }]
}

To easily create the query with the interpolated value of <userId>, you can use a computed key in your object (ES6 syntax):

{
    $or:[{
        author: this.userId
    } , {
        // The query computed key must be in square brackets.
        // Specify the field child key using the dot notation within your query.
        ["sharedwith." + this.userId]: true
    }]
}

Or with good old ES5 syntax, similarly to @MichelFloyd's answer:

var query = {
        $or: [{
            author: this.userId
        }]
    };
var newCondition = {};

newCondition["sharedWith." + this.userId] = true;
query.$or.push(newCondition);

Note: the above described document structure could conveniently replace the sharedWith hash map by an array (since having a false value for the boolean could simply be replaced by removing the corresponding userId from the array):

{
    author: string,
    sharedWith: [
        <userId1>
        // <userId2>…
    ]
}

In which case the query would simply become:

{
    $or:[{
        author: this.userId
    } , {
        // In MongoDB query, the below selector matches either:
        // - documents where `sharedWith` value is a string equal to
        //     the value of `this.userId`, or
        // - documents where `sharedWith` value is an array which contains
        //     an element with the same value as `this.userId`.
        sharedwith: this.userId
    }]
}

Upvotes: 2

Michel Floyd
Michel Floyd

Reputation: 20226

Try building the query as a variable before running it.

let query = { $or: [{ author: this.userId }]};
const sw = sharedwith[this.userId];
query.$or.push({sw: true});
MyCollection.find(query);

Upvotes: 0

Related Questions