Mongo query condition using IN? - mongodb

I wonder if there's anything similar to mysql IN? Like this "where id in (1,3,5)"?
I have this in my group by condition and i want to do filter only certain ids and those ids are like the above case where using gte/lt once will be able to do the job.
Maybe not just for group by but find. Any help will be great. Thanks.
{"time" : {"$gte" : "2015-12-16", "$lt" : "2015-12-16"}}

You mean, like:
{ field: { $in: [1,3,5] } }
No. There's nothing like that in mongodb. Trust me. Nothing like that.

Related

Count documents based on Array value and inner Array value

Before I explain my use case, I'd like to state that yes, I could change this application so that it would store things in a different manner or even split it into 2 collections for that matter. But that's not my intention, and I'd rather want to know if this is at all possible within MongoDB (since I am quite new to MongoDB). I can for sure work around this problem if I'd really need to, but rather looking for a method to achieve what I want (no I am not being lazy here, I really want to know a way to do this).
Let's get to the problem then.
I have a document like below:
{
"_id" : ObjectId("XXXXXXXXXXXXXXXXXXXXX"),
"userId" : "XXXXXXX",
"licenses" : [
{
"domain" : "domain1.com",
"addons" : [
{"slug" : "1"},
{"slug" : "2"}
]
},
{
"domain" : "domain2.com",
"addons" : [
{"slug" : "1"},
]
}
]
}
My goal is to check if a specific domain has a specific addon. When I use the below query to count the documents with domain: domain2.com and addon slug: 2 the result should be: 0. However with the below query it returns 1. I know that this is because the query is executed document wide and not just the license index that matched domain2.com. So my question is, how to do a sub $and (or however you'd call it)?
db.test.countDocuments(
{$and: [
{"licenses.domain": "domain2.com"},
{"licenses.addons.slug": "2"},
]}
)
Basically I am looking for something like this (below isn't working obviously), but below should return 0, not 1:
db.test.countDocuments(
{$and: [
{
"licenses.domain": "domain2.com",
$and: [
{ "licenses.addons.slug": "2"}
]
}
]}
)
I know there is $group and $filter operators, I have been trying many combinations to no avail. I am lost at this point, I feel like I am completely missing the logic of Mongo here. However I believe this must be relatively easy to accomplish with a single query (just not for me I guess).
I have been trying to find my answer on the official documentation and via stack overflow/google, but I really couldn't find any such use case.
Any help is greatly appreciated! Thanks :)
What you are describe is searching for a document whose array contains a single element that matches multiple criteria.
This is exactly what the $elemMatch operator does.
Try using this for the filter part:
{
licenses: {
$elemMatch: {
domain: "domain2.com",
"addons.slug": "2"
}
}
}

MongoDB - Find documents which contain an element in an array which has a property of null

I'm struggling with a seemingly simple query in mongodb.
I have a job collection that has objects like:
{
"_id" : ObjectId("5995c1fc3c2a353a782ee51b"),
"stages" : [
{
"start" : ISODate("2017-02-02T22:06:26Z"),
"end" : ISODate("2017-02-03T22:06:26Z"),
"name" : "stage_one"
},
{
"start" : ISODate("2017-02-03T22:06:26Z"),
"end" : ISODate("2017-02-07T20:34:01Z"),
"name" : "stage_two"
}
]
}
I want to get a job whose second stage does not have an end time, i.e. end is null or not defined.
According to the mongo docs on querying for null and querying an array of embedded documents, it would seem the correct query should be:
db.job.findOne({'stages.1.end': null})
However, running that query returns me the job above which does have a non-null end date. In fact, if I run the query with count instead of findOne, I see that all jobs are returned - no filtering is done at all.
For completeness, here is the output from an example on a fresh mongo instance:
So in this example, I would expect db.job.findOne({'stages.1.end': null}) to return nothing since there is only one document and its second stage has a non-null end date.
This feels like the sort of issue where it's just me being an idiot and if so, I apologise profusely.
Thanks in advance for your help and let me know if you need any more details!
EDIT:
After some more experimentation, I think I can achieve what I want with the following:
db.job.find({$or: [{'stages.1.end': { $type: 10 }}, {'stages.1.end': {$exists: false}}]})
While this gets the job done, it doesn't feel like the simplest way and I still don't understand why the original query doesn't work. If anyone could shed some light on this it'd be much appreciated.

mongodb query in 2 collections

I have define 2 reconds in 2 collections separately in one mongo db like this
order:
{
"_id" : ObjectId("53142f58c781abdd1d836fcd"),
"number" : "order1",
"user" : ObjectId("53159bd7d941aba0621073e3")
}
user
{
"_id" : ObjectId("53159bd7d941aba0621073e3"),
"name" : "user1",
"gender" : "male"
}
when I use this command in console, it can not execute
db.orders.find({user: db.user['_id']}) or db.orders.find({user: user['_id']}),
is there anything wrong? Thanks!
Another way is to:
> var user = db.users.findOne({name: 'user1'});
> db.orders.find({user: user._id});
This way can be a bit more flexible especially if you want to return orders for multiple users etc.
Taking your comment:
Thanks, but actually, I want to search all the orders of all users, not only one user. So what would I do? Thanks
db.users.find().forEach(function(doc){
printJson(db.orders.find({user: doc._id}));
});
I think you want:
db.order.find({'user':db.users.findOne({'name':'user1'})._id})
All you need to do is to make a query and check the output before inserting it into the query.
i.e. check that:
db.users.findOne({'name':'user1'})._id
has the output:
ObjectId("53159bd7d941aba0621073e3")
If you want to run larger queries, you're going to have to change your structure. Remember that Mongodb doesn't do joins so you'll need to do create a user document that looks like this:
user
{
"name":"user1",
"gender":"male",
"orders":[
{
'number':'order1'
}
]
}
You can then update this using:
db.user.update({'_id':ObjectId('blah')}, {'orders':{$push:{'number':'order2'}})
This will then start you with order tracking.
Mongo will be able to find using the following:
db.user.find({'orders.numbers':'order2'})
returning the full user record
Maybe you can help this solution:
use orders
db.getCollection('order').find({},{'_id':1})
db.getCollection('user').find({},{'_id':1})

mongoDB select from collection with relation

I need to select users for corresponding data from query.
I have this collection in my DB (two or more rows are output of my query as well)
> db.Friends.find()
{ "userId" : "k3XCWdN5M2pbzBiFD", "followeeId" : "3MTmHcJNEzaaS8hrd","_id" : "aiRD.." }
{ "userId" : "k3XCWdN5M2pbzBiFD", "followeeId" : "SoTozuZ4nWooRBeFz","_id" : "QingX.." }
When it would be just one result as findOne(...) the second query would looks like this:
users.findOne({ _id: firstQueryResult.followeeId })
But now the problem is... how can i select the users from users collection when i dont have only one followeeId but more of them?
Please someone show me an example of code.
My research:
Is this a good solution?
friendsData.forEach(function(relationShip) {
followeeIds.push(relationShip.followeeId);
});
console.log(followeeIds);
Ok i finalllly figure out the problem.For next readers:
Check if autopublish is enabled or disabled.
If is disabled you need to publish the collection from the DB
Meteor.publish("userData", function () {
return Meteor.users.find({},
{fields: {'username': 1}});
});
PS: i want to publish only username field and thats all!
You need to subscribe the data as well!
Meteor.subscribe("userData");
Now you can access other users data this way:
users= Meteor.users.findOne({username: "Nolifer"});
To my original problem ... i will probably use this function for iterate over more then one row result(its more a SQL term but i am not sure what term use in mongoDb maybe a document? whatever):
users.forEach(function(user) {
console.log(user);
});
Thats it!
P.S.: I think there is nothing wrong on this but what i know right? :) So if someone know a better way please leave a comment. If not give me know if it was useful for you :)
According to the mongo manual, use the $in operand: http://docs.mongodb.org/manual/reference/operator/in/#op._S_in
db.inventory.find( { qty: { $in: [ 5, 15 ] } } )

use $lt or $gt operator in mongodb queries

My collection structure*"countcollection"* is looks as below
{
"limitcount": 10000,
"currentcount": 100
}
I want to right the mongoquery that able to compare the currentcount<($lt)limitcount
or currentcount>($gt)limitcount.
First, i wrote the mongo query as below
db.countcollection.find({"currentcount":{$lt:{"limitcount"}}});
db.countcollection.find({"currentcount":{$gt:{"limitcount"}}});
but it's failed to execute .
please give your input for this mongoquery.
thanks in advance .
javaamtho.
As Bugai13 said, you can't do a comparison on 2 fields in a query.
The problem with $where is performance - as that is a javascript function that will be executed for every document so it will have to scan through every one.
So, you could store another field (that you could then index) alongside those existing fields
e.g.
{
"limitcount": 10000,
"currentcount": 100,
"remainingcount" : 9900
}
so you could then query on the new field instead:
db.countcollection.find({"remainingcount" : {$gt : 0}})
db.countcollection.find({"remainingcount" : {$lt : 0}})
You can't do what you want using simple query(like you have tried above). There is such bug in mongodb jira and you can vote up for this.
I suppose you shoud use javascript expression like this:
db.countcollection.find( { $where: "this.currentcount < this.limitcount" } );
Hope this help.
$gt:{"limitcount"}}
does not make any sense since you are comparing against the string limitcount. If you want to compare against a pre-defined variable, use the variable but something with quotes around it. Why did you choose this strange syntax?