user3766930 user3766930 - 1 month ago 11
Node.js Question

My mongodb/mongoose query conditions exclude themselves. Can you help me fixing that?

When user submits a content into my

node.js
app, he puts four things: start_date, his facebook username, text content and a flag, whether the content should be visible to everyone or only to his facebook friends.

When user fetches content, he can get the public content from other users and the content from his facebook friends (even when they submitted their content only for their friends).

I created a
mongoose
query that works correctly in this scenario. I do it like this:

var query = Test.find({})

if(startDate != undefined) {
var startDate = new Date(req.param('startDate'));
query = query.where('updated_at').gte(startDate);
}

if (friends != undefined) {
var friendsSplitted = friends.split(",");
for(var i=0; i<friendsSplitted.length; i++) {
query = query.or([{ 'facebook_username': friendsSplitted[i] }]);
}
}

query = query.where('hidden').equals(false);

if (publicFlag != undefined && publicFlag === "true") {
query = query.or({friends_only: false});
}


With that code above, when user queries only for content from his friends (that might be private or public), he
POST
s
startDate
, an array of his
friends
, a flag
hidden
set to false and
publicFlag
set to false. A query is constructed:


Mongoose: test.find({ updated_at: { '$gte': new Date("Sat, 15 Oct 2011
00:00:00 GMT")}, hidden: false, '$or': [ { facebook_username:
'XXXXXXXXXXXXXX' }, { facebook_username: 'YYYYYYYYYYYYYYY' } ] }) {
fields: undefined }


User can also query not only his friends (private or public) content, but also public content of everyone else. For that, he
POST
s
startDate
, an array of his
friends
, a flag
hidden
set to false and
publicFlag
set to true. A query is constructed:


Mongoose: test.find({ updated_at: { '$gte': new Date("Sat, 15 Oct 2011
00:00:00 GMT")}, hidden: false, '$or': [ { facebook_username:
'XXXXXXXXXXXXXX' }, { facebook_username: 'YYYYYYYYYYYYYYY' }, {
friends_only: false } ] }) { fields: undefined }


Above code works fine.

I want to add another case, when user can fetch content with specific hashtags.
Basically, when user selects this option, he can see other users' content that only includes those hashtags. That content though is his fb friends posts (private or public) and other people's posts (that is public).

For that I thought about adding this condition to my original
node.js
code:

if (hashtagsInput != undefined) {
var hashtags = hashtagsInput.split(",");

for(var i=0; i<hashtags.length; i++) {
query = query.or([{ 'hashtags': hashtags[i] }]);
}
}


but this solution does not work properly.

When user wants to fetch (private and public) content of his friends and public content of others - but only that one that contains one of the hashtags - he
POST
s
startDate
, an array of his
friends
, a flag
hidden
set to false,
publicFlag
set to true and an array of his
hashtags
. When he does it, it creates a query:


Mongoose: test.find({ updated_at: { '$gte': new Date("Sat, 15 Oct 2011
00:00:00 GMT")}, '$or': [ { hashtags: 'test1' }, { hashtags: 'test2'
}, { facebook_username: 'XXXXXXXXXXXX' }, { facebook_username:
'YYYYYYYYYYYYYYYYYY' }, { friends_only: false } ], deleted: false }) {
fields: undefined }


Basically I want to limit the general query only to specific hashtags.

This query does not return correct data. Now I'm not a
mongoose
specialist and I've spent couple hours yesterday of trying to figure it out, but I think the problem is that it returns the data that either contains one of the hashtags OR its author is one of my facebook friend.

I would like to fix this query so that - in case user
POST
s hashtags - it fetches the content that is public and private of his friends and public of everyone, but only that one that contains at least one of those hashtags. And when user does not provide the hashtags - it should work as it was, fetching all private and public content of his friends and public of everyone.

Can you please help me fix my
node.js
code so that it creates a correct
mongoose
query?

Answer

The below code will work as you want

var query= {};
query.$and = [];

// and condition on start date
if(startDate != undefined) {
    var startDate = new Date(req.param('startDate'));
    query.$and.push({"updated_at":{$gte: startDate}});
}

// and condition on hastags
if (hashtagsInput != undefined) {
    var hashtags = hashtagsInput.split(",");
    query.$and.push({"hashtags":{$in: hashtags}});
}

// and condition on hidden
query.$and.push({"hidden":false});


// creating a OR condition for facebook friends and public flag
var friend_query = {};
friend_query.$or = [];

if (friends != undefined) {
    var friendsSplitted = friends.split(",");
    friend_query.$or.push({"facebook_username":{$in: friendsSplitted}});
}

if (publicFlag != undefined && publicFlag === "true") {
    friend_query.$or.push({friends_only: false});
}

//Merging facebook friend condition with other condition with AND operator.
query.$and.push(friend_query);


var finalquery = Test.find(query)

Sorry I use to create mongodb query directly in Json format, it is little different than you are doing. This will work as you mentioned you want in question.

If it don't solve your problem tell me.