mongodb - how to empty out a hash - mongodb

In mongodb. I have the following document/json with these (4) fields.
"ready_state" : {
"user" : "abcd#abc.com",
"state" : "green",
"audit_date" : ISODate("2016-04-03T14:27:11.494Z"),
"profile" : "tst"
},
How do I empty out this hash? Output expected would be:
"ready_state" : {
},
Can someone provide example on how to do so using pull and set?

You simply replace the value of ready_state with the new value. Using $set you can do something like this:
db.collection.update(query, { $set: { ready_state: {} });

Related

MongoDB query returning no results

I'm new to mongo and am trying to do a very simple query in this collection:
{
"_id" : ObjectId("gdrgrdgrdgdr"),
"administrators" : {
"-HGFsfes" : {
"name" : "Jose",
"phone" : NumberLong(124324)
},
"-HGFsfqs" : {
"name" : "Peter",
"phone" : "+43242342"
}
},
"countries" : {
"-dgfgrdg : {
"lang" : "en",
"name" : "Canada"
},
"-grdgrdg" : {
"lang" : "en",
"name" : "USA"
}
}
}
How do I make a query that returns the results of administrators with name like "%Jos%" for example.
What I did until now is this: db.getCollection('coll').find({ "administrators.name": /Jos/});
And variations of this. But every thing I tried returns zero results.
What am I doing wrong?
Thanks in advance!
Your mistake is that administrators is not an array, but an object with fields that are themselves objects with name field. Right query will be
{ "administrators.-HGFsfes.name": /Jos/}
Unfortunatelly this way you're only querying -HGFsfes name field, not other administrator name field.
To achieve what you want, the only thing to do is to replace administrators object by an array, so your document will look like this :
{
"administrators" : [
{
"id" : "-HGFsfes",
"name" : "Jose",
"phone" : 124324
},
{
"id" : "-HGFsfqs",
"name" : "Peter",
"phone" : "+43242342"
}
],
countries : ...
}
This way your query will work.
BUT it will return documents where at least one entry in administrators array has the matching name field. To return only administrator matching element, and not whole document, check this question and my answer for unwind/match/group aggregation pipeline.
You need to use query like this:
db.collection_name.find({})
So if your collection name is coll, then it would be:
db.coll.find({"administrators.-HGFsfes.name": /Jos/});
Look this for like query in mongo.
Also, try with regex pattern like this:
db.coll.find({"administrators..-HGFsfes.name": {"$regex":"Jos", "$options":"i"}}});
It will give you only one result because your data is not an array as below in screenshot:
If you want multiple results, then you need to restructure your data.
Ok, think i've found a better solution for you, with aggregation framework.
Run the following query on your current collection, will return you all administrators with name "LIKE" jos (case insensitive with i option) :
db.test1.aggregate(
[
{
$project: {
administrators:{ $objectToArray: "$administrators"}
}
},
{
$unwind: {
path : "$administrators"
}
},
{
$replaceRoot: {
newRoot:"$administrators"
}
},
{
$match: {
"v.name":/jos/i
}
},
]
);
Output
{
"k" : "-HGFsfes",
"v" : {
"name" : "Jose",
"phone" : NumberLong(124324)
}
}
"k" and "v" are coming from "$objectToArray" operator, you can add a $project stage to rename them (or discard if k value doesn't matter)
Not sure for Robomongo testing but in Studio 3T, formerly Robomongo, you can either copy/paste this query in Intellishell console, or copy/import in aggregation tab, (small icon 'paste from the clipboard').
Hope it helps.

MongoDB filter array element in a nested object

I have a document as follows:
{
"_id" : ObjectId("56423b2558cb340599108b35"),
"test" : {
"source" : [
{
"member" : "abc"
},
{
"member" : "xyz"
}
]
}
}
I want to filter on the array element xyz, and I am trying the following query:
db.coll.find({ "test.source.member" : "xyz" }, { "test.source.$.member" : true }).pretty()
Apparently it used to work on 2.4, on 2.6 it does not work,
On 2.4 it returned the "xyz", whereas on 2.6 it returns "abc" i.e. the first element. Is there a way to filter "abc" because eventually i want to update. BTW, i also tried with $elemMatch and it seems to give the same output "abc".
Thanks.
According to the Docs, if you are running 2.6, this should give you the correct output:
db.coll.find({ "test.source.member" : "xyz"}, { "test.source.$" : 1}).pretty()
You could extract the member by doing this:
var member = db.coll.find(
{ "test.source.member" : "xyz"},
{ "test.source.$" : 1}
).test.source[0].member;
The value of member would be:
xyz

How to return specific field's value in mongodb

how can I return a specific value for a specific document in MongoDB? For example, I have a schema that looks like:
{
"_id" : "XfCZSje7GjynvMZu7",
"createdAt" : ISODate("2015-03-23T14:52:44.084Z"),
"services" : {
"password" : {
"bcrypt" : "$2a$10$tcb01VbDMVhH03mbRdKYL.79FPj/fFMP62BDpcvpoTfF3LPgjHJoq"
},
"resume" : {
"loginTokens" : [ ]
}
},
"emails" : {
"address" : "abc123#gmu.edu",
"verified" : true
},
"profile" : {
"companyName" : "comp1",
"flagged" : true,
"phoneNum" : "7778883333"
}}
I want to return and store the value for profile.flagged specifically for the document with _id : XfCZSje7GjynvMZu7. So far I have tried:
db.users.find({_id:'myfi3E4YTf9z6tdgS'},{admin:1})
and
db.users.find({_id: 'myfi3E4YTf9z6tdgS'}, {profile:admin});
I want the query to return true or false depending on the assigned value.
Can someone help? Thanks!
MongoDB queries always return document objects, not single values. So one way to do this is with shell code like:
var flagged =
db.users.findOne({_id: 'myfi3E4YTf9z6tdgS'}, {'profile.flagged': 1}).profile.flagged;
Note the use of findOne instead of find so that you're working with just a single doc instead of the cursor that you get with find.
The correct answer here is the method .distinct() (link here)
Use it like this:
db.users.find({_id:'myfi3E4YTf9z6tdgS'},{admin:1}).distinct('admin')
The result will be: 1 or 0

Mongodb field name as numbers - how to use it in updates?

Because of a weird bug in my code, I have a collection with field names which are stricly numbers (ex: 34344,54675,34356).
Now I try to move these fields values to another fields (ex: name,email,etc) but when I run the update command:
db.collection.find({"id_field" : 1996}).forEach(function (elem) {db.collection.update({_id: elem._id},{$set: {name: elem.36536}});});
All I get is an error:
SyntaxError: Unexpected number
How should I handle it? I already tried with elem[36536] instead elem.36536 but without success.
if I got your problem right, this code might help you:
db.collection.find({"id_field" : 1996}).forEach(function (elem)
{
var value = elem['36536'];
db.collection.update({_id: elem._id},{$set: {name: value}});
});
If your document is like this
{
"_id" : 1,
"elem" : {
"123" : "barno",
"456" : "foo#gmail.com"
}
}
you can $rename the key document.
db.d.update({"_id" : 1},{$rename:{'elem.123':'elem.name','elem.456':'elem.email'}})
Result:
{
"_id" : 1,
"elem" : {
"name" : "barno",
"email" : "foo#gmail.com"
}
}

Update MongoDB objects using existing objects

I'm trying to convert my mongodb data into more simpler format, but I don't know how to check if certain field is an array and update those only.
I have this kind of objects in my database currently
{ "_id" : ObjectId("xyz"), "name" : "Yeti ", "channel" : "ABC", "showed" : { "_isAMomentObject" : true, "_i" : "25.3.2014 23:40", ... }}
I also has some rows which are in new format already:
{ "_id" : ObjectId("xyz"), "name" : "Yeti ", "channel" : "ABC", "showed" : "25.3.2014 23:40" }
I would like to update all my objects which has array type in "showed" property into an object which has showed._i in showed property.
showed._i => showed, for all objects which have array in showed property.
I tried to do this update using my backup collection, but it put null into showed property for all objects:
db.programs_bak.find({}).forEach(function(doc) { db.programs.update( { _id: doc._id }, { showed: doc.showed._i },{ }); });
db.programs_bak.find({}).forEach(function(doc) {
db.programs.update( { _id: doc._id },
{$set : { "showed" : doc.showed._i}});
});