2

Related to: mongodb/meteor collection check if subdocument field exists when field is a variable

I'm trying to query a Meteor collection by building an object with some variable field names. This works when the object has one field, for example

var query = {};
query['myField.'+myVariable] = {$exists: true};
Collection.find(query); //works fine

But I need to query with multiple selectors. For example, I need to check that a field name with a variable exists, and also check if some other field = true, and if some other field = a variable. So I'm trying to find a general way to build query objects. I have tried the following:

var query = {};
query['myField.'+myVariable] = {$exists: true};
query[newField] = false;
Collection.find(query);

This doesn't work. I'm not sure if that's because the 'newField' is not of type Object or something.

I've tried also using the $and selector to see if that works but I don't think the syntax I'm using is exactly correct...

var query = {};
var object = {};
object['myField'.+myVariable] = {$exists: true};
query['$and'] = [object, {newField: false}];
Collection.find(query);

This also doesn't work. I was trying to build with the mongo $and selector which works by using an array.

How do I syntactically build a Meteor collection query with javascript object notation and object literals? I feel like either one of these should work.

To be specific, I'm looking for the following (semi pseudocode since getting a subdocument/subobject with dot notation doesn't work with a mongo query)

Collection.find({correlated: false, readBy.(Meteor.userId()): {$exists: true} ...)

I also thought this should work:

var query = {};
query['myField.'+myVariable] = {$exists: true};
Collection.find(query, {otherField: false}) 
//OR 
var query2 = {};
query['priority'] = false;
Collection.find(query, query2)

But neither of them do.

EDIT: example doc. I want to find the document such that the current user ID is NOT a readBy field AND has correlated: false

{
    "_id" : ObjectId("55b6868906ce5d7b1ac6af10"),
    "title" : "test",
    "correlated" : "false",
    "readBy" : {
        "DXqLhesDEJq4ye8Dy" : ISODate("2015-07-27T18:29:43.592Z")
    }
}
4
  • The pseudo code is the most important line of this whole question. Can you make sure it encompasses everything you want out of the query? I.e. don't leave anything out. Commented Jul 27, 2015 at 18:48
  • It's important to know that mongo queries are just JavaScript objects, so the notation doesn't matter. The query object in your second code block looks correct to me, I'm just supposing your query is not finding anything, as opposed to not working. Commented Jul 27, 2015 at 18:50
  • And what do you mean by It doesn't work? What is your documents structure? Commented Jul 27, 2015 at 18:52
  • I will check to see if its just that the query doesn't return any documents but they are structured as follows: each document has a field called readBy which is an object. The fields of this object are the userIds and the value of these fields is the timestamp. I then have another field separate from that called correlated which is either true or false. I want to find every document that has the userId field in the readBy subdocument AND has correlated = false. Commented Jul 27, 2015 at 18:59

1 Answer 1

1

There is only one selector argument to a find. So this:

Collection.find(query, {otherField: false})

is not correct. query would have to contain the information about otherField. Have a close look at this example code:

// 'readBy.abc123'
var key = 'readBy.' + Meteor.userId();

// build the selector by parts
var selector = {correlated: false};
selector[key] = {$exists: false};

// selector should now be something like:
// {correlated: false, 'readBy.abc123': {$exists: false}}
// note that these are ANDed together so all conditions must be true

// here's a cursor you can use to fetch your documents
var cursor = Collection.find(selector);

// log one of the selected documents
console.log(Collection.findOne(selector));
Sign up to request clarification or add additional context in comments.

4 Comments

I see why the latter two are wrong and the syntax makes sense, thanks. There's probably a database reason why they aren't getting, but the query is so simple I'm not sure why I'm not getting results.
I think it is possible that I have to wrap correlated and false in a string like `var selector = {'correlated':'false'} Because when I try to use findOne from the console I don't get anything unless I do that.
In your question, I'd recommend showing an example document that you are trying to select.
Okay, I updated the answer to match the actual problem. Hopefully that will work for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.