$not not performing $and operation - javascript

I just started exploring mongoDB. During that time I managed to create a simple collection with the following data,
db.test.insert({name : "joe", age : 20});
db.test.insert({name: "james", age : 25});
Now I have queried it by using,
db.test.find({name : {$not : {$eq : "joe", $eq: "james"}}})
It yielded me the following result,
{name : "joe", age : 20}
I am confused here, Is it not an and operation like below,
SELECT * FROM test where not name = "joe" and not name = "james"
Doubt1: If yes then how the above mentioned mongo query can be interpreted as a normal mysql query? [Note : I am coming from a mysql background.] Please explain.
Doubt2: Also explain about the following mongo query,
db.test.find({name : "joe", age : 20});
Is the above query equals to select * from test where name='joe' and age=20 ? If not then how it would be interpreted as a normal mysql query?

When you are creating an object with {$eq : "joe", $eq: "james"} you are using the same object key twice. So james will overwrite joe because both use the same object key $eq.
To do your query, you can try something like NOT (name = "joe" OR name = "james"). So you add the OR to your mongo query:
db.test.find({name : {$nor: [{$eq: "joe"}, $eq: "james"]}})
Reference

I guess Christoph cleared your doubts.
For SQL to Mongo Query reference visit this link

Related

Query orderByChild in Firebase Realtime Database not working?

I've seen many posts and solutions that are precisely what I need but when I implement it it doesn't work. I'm using the Firebase Realtime Database and I'm trying to search all "Name" children for a specific name. In this example I added the strings directly, but I'll be using a variable based on user input in the future. Here is my database structure as I see it in firebase:
{
"kjienk24dfwefn" : {
"FriendID" : "fr1959l9591i4925a",
"Name" : "Test Dummy2",
"email": "something#gmail.com",
"Status" : "InGame"
},
"kjienk24kdfiwne" : {
"FriendID" : "fr2812p8092m3604l",
"Name" : "Test Dummy",
"email":"some#something.com"
"Status" : "Online"
},
"kjienk24udfjjo" : {
"FriendID" : "fr7605h9204f8099g",
"Name" : "Test Dummy3",
"email": "fake#fakeemail.com"
"Status" : "Offline"
}
}
And here is the code I'm using to query the "Name" (usersRef points to "firebase.database().ref()"). I've seen lots of examples of this online and I'm not sure what I'm doing incorrectly.
usersRef.orderByChild("Name").equalTo("Test Dummy").on("value", function(snapshot) {
//This is where I expect to see Test Dummy on the console.
console.log(snapshot.val())
});
EDIT: Here is the initialization of usersRef. Haven't had any problems reading and writing to the database. Standard firebaseConfig.:
const fbApp = firebase.initializeApp(firebaseConfig);
const db2 = fbApp.database("https://firebasedatabaseurl.com/")
const usersRef = db2.ref();
Test with parent node:
Thanks all in advance!
You want to load data from the users node, but that is currently not mentioned anywhere in your code. So Firebase is querying the root of your database, and the child nodes under there (like users) don't have a Name property, so you get no results.
const usersRef = db2.ref().child("users");
Or:
const usersRef = db2.ref("users");

reduce mongo db query to pure array

when i run db.abhishek.em.find({}) I have
{ "_id" : ObjectId("5ac62d35b075e574b3e7eeaa"), "name" : "first", "employed" : true }
{ "_id" : ObjectId("5ac62d3fb075e574b3e7eeab"), "name" : "second", "employed" : true }
{ "_id" : ObjectId("5ac62d4eb075e574b3e7eeac"), "name" : "third", "employed" : false }
I want to reduce this result into an array of simple object ids like this by adding or chaining something to find function , something like
db.a.b.find({employed:true}).somefunction() which can return the below array
I want to use the command nested with $in in a bigger query to achieve some sort of relational querying
[
ObjectId("5ac62d35b075e574b3e7eeaa"),
ObjectId("5ac62d3fb075e574b3e7eeab")
]
-----------------EDIT----------------------
For an example case I want to get employed employees by running
db.abhishek.another.find({id:{$in:db.abhishek.em.find({employed:true},{_id:1}).toArray()}})
or something similiar as this command is not working
The db.a.another collection is
{ "_id" : ObjectId("5ac63de1b075e574b3e7eead"), "id" : ObjectId("5ac62d35b075e574b3e7eeaa"), "name" : "Lets say person 1" }
{ "_id" : ObjectId("5ac63df7b075e574b3e7eeae"), "id" : ObjectId("5ac62d3fb075e574b3e7eeab"), "name" : "Lets say person 2" }
{ "_id" : ObjectId("5ac63e06b075e574b3e7eeaf"), "id" : ObjectId("5ac62d4eb075e574b3e7eeac"), "name" : "Lets say person 3" }
-----------------EDIT----------------------
Solved see my answer below
Use MongoDB to only provide those fields from the model. In MongoDB terms this is called Projection. There is a MongoDB method .project() that you can chain onto your query like this:
db.abhishek.em.find({}).project({});
that should do it. If you want to explicit exclude fields, you do:
db.abhishek.em.find({}).project({name:0, employed:0});
then, finally, to get the output in array form do:
db.abhishek.em.find({}).project({name:0, employed:0}).toArray();
Reference here:
https://docs.mongodb.com/manual/tutorial/project-fields-from-query-results/
Thanks everyone for providing directions and suggestions to move forward,
I was able to successfully do some sort of relational based query using the following
db.abhishek.another.find({id:{$in:db.abhishek.em.find({employed:true},{_id:1}).map(function(e) {return e._id})}},{name:1,_id:0})
It gave this as output
{ "name" : "Lets say person 1" }
{ "name" : "Lets say person 2" }
This query took all records from em collection with employed set to true,form its array and then pass it to $in operator on query for "another" collection to give output
toArray method used to convert objects nested in array hence failing $in operator
Thanks #veeram for telling about selection of fields

Meteor Mongo not working but standalone MongoDB is

I have the following document
{
"_id" : ObjectId("5464e68481f8252e74f6e0ef"),
"message" : "Hello World!",
"timestamp" : ISODate("2014-11-13T17:12:36.547Z"),
"sender" : "D3EkLv8vatX3xfCGE",
"receiver" : [
{
"id" : "YzhZchz4AwCAd3q2R",
"seen" : false
},
{
"id" : "sm2W28EKYmHz29Aoj",
"seen" : false
}
],
"saved" : false
}
That's the basic structure. Now I want to get all the documents that have the current user's ID. The id can be in the sender field or one of the object in the receiver array. This works fine:
db.messages.find({ sender: "D3EkLv8vatX3xfCGE" })
But the following query doesn't work on the Meteor Mongo instance but does so in Mongo 2.6:
db.messages.find({ receiver: {id: "YzhZchz4AwCAd3q2R"} })
Is there any way I can get this to work. Also, the above query works on Minimongo but doesn't work on Meteor's bundled mongo(meteor mongo) which is currently at v2.4.9.
On mongo shell this query seems to work:
db.messages.find({ "receiver.id": "YzhZchz4AwCAd3q2R"} )
You can find all of the documents were a particular user is a receiver using receiver.id in your selector like so:
Messages.find({'receiver.id': 'YzhZchz4AwCAd3q2R'})
If you wanted to find all documents where a particular user was either a receiver or a sender you could do this:
var id = 'YzhZchz4AwCAd3q2R';
Messages.find({$or: [{'receiver.id': id}, {sender: id}]});

MongoDB aggregation: How to extract the field in the results

all!
I'm new to MongoDB aggregation, after aggregating, I finally get the result:
"result" : [
{
"_id" : "531d84734031c76f06b853f0"
},
{
"_id" : "5316739f4031c76f06b85399"
},
{
"_id" : "53171a7f4031c76f06b853e5"
},
{
"_id" : "531687024031c76f06b853db"
},
{
"_id" : "5321135cf5fcb31a051e911a"
},
{
"_id" : "5315b2564031c76f06b8538f"
}
],
"ok" : 1
The data is just what I'm looking for, but I just want to make it one step further, I hope my data will be displayed like this:
"result" : [
"531d84734031c76f06b853f0",
"5316739f4031c76f06b85399",
"53171a7f4031c76f06b853e5",
"531687024031c76f06b853db",
"5321135cf5fcb31a051e911a",
"5315b2564031c76f06b8538f"
],
"ok" : 1
Yes, I just want to get all the unique id in a plain string array, is there anything I could do? Any help would be appreciated!
All MongoDB queries produce "key/value" pairs in the result document. All MongoDB content is basically a BSON document in this form, which is just "translated" back to native code form by the driver to the language it is implemented in.
So the aggregation framework alone is never going to produce a bare array of just the values as you want. But you can always just transform the array of results, as after all it is only an array
var result = db.collection.aggregate(pipeline);
var response = result.result.map(function(x) { return x._id } );
Also note that the default behavior in the shell and a preferred option is that the aggregation result is actually returned as a cursor from MongoDB 2.6 and onwards. Since this is in list form rather than as a distinct document you would process differently:
var response = db.collection.aggregate(pipeline).map(function(x) {
return x._id;
})

how to push a dictionary to a nested array with mongodb?

i have data that looks like this in my database
> db.whocs_up.find()
{ "_id" : ObjectId("52ce212cb17120063b9e3869"), "project" : "asnclkdacd", "users" : [ ] }
and i tried to add to the 'users' array like thus:
> db.whocs_up.update({'users.user': 'usex', 'project' : 'asnclkdacd' },{ '$addToSet': { 'users': {'user':'userx', 'lastactivity' :2387843543}}},true)
but i get the following error:
Cannot apply $addToSet modifier to non-array
same thing happens with push operator, what im i doing wrong?
im on 2.4.8
i tried to follow this example from here:
MongoDB - Update objects in a document's array (nested updating)
db.bar.update( {user_id : 123456, "items.item_name" : {$ne : "my_item_two" }} ,
{$addToSet : {"items" : {'item_name' : "my_item_two" , 'price' : 1 }} } ,
false ,
true)
the python tag is because i was working with python when i ran into this, but it does nto work on the mongo shell as you can see
EDIT ============================== GOT IT TO WORK
apparently if i modify the update from
db.whocs_up.update({'users.user': 'usex', 'project' : 'asnclkdacd' },{ '$addToSet': { 'users': {'user':'userx', 'lastactivity' :2387843543}}},true)
to this:
db.whocs_up.update({'project' : 'asnclkdacd' },{ '$addToSet': { 'users': {'user':'userx', 'lastactivity' :2387843543}}},true)
it works, but can anyone explain why the two do not achieve the same thing, in my understanding they should have referenced the same document and hence done the same thing,
What does the addition of 'users.user': 'userx' change in the update? does it refer to some inner document in the array rather than the document as a whole?
This is a known bug in MongoDB (SERVER-3946). Currently, an update with $push/$addToSet with a query on the same field does not work as expected.
In the general case, there are a couple of workarounds:
Restructure your update operation to not have to query on a field that is also to be updated using $push/$addToSet (as you have done above).
Use the $all operator in the query, supplying a single-value array containing the lookup value. e.g. instead of this:
db.foo.update({ x : "a" }, { $addToSet : { x : "b" } }, true)
do this:
db.foo.update({ x : { $all : ["a"] } }, { $addToSet : { x : "b" } } , true)
In your specific case, I think you need to re-evaluate the operation you're trying to do. The update operation you have above will add a new array entry for each unique (user, lastactivity) pair, which is probably not what you want. I assume you want a unique entry for each user.
Consider changing your schema so that you have one document per user:
{
_id : "userx",
project : "myproj",
lastactivity : 123,
...
}
The update operation then becomes something like:
db.users.update({ _id : "userx" }, { $set : { lastactivity : 456 } })
All users in a given project may still be looked up efficiently by adding a secondary index on project.
This schema also avoids the unbounded document growth of the above schema, which is better for performance.

Categories