Random number generation in mongodb within a range - json

I have a collection in which I want to add a new field and in that field i want to randomly assign values between 1 and 44 in mongo db.
I have already tried math.random() which is not working.
{ $addFields:{ PoS_ID: { $switch:{ branches:[ { case: {$and : [{$gte: ["$user_id", 0]}, {$lte: ["$user_id", 10000]}]}, then:1 }, { case: {$and : [{$gte: ["$user_id", 10000]}, {$lte: ["$user_id", 15000]}]}, then:2 } ], default: -1 } } } }
This lets me assign pos_ids from 1 to 44 to different user ids based on conditions.But I want to simply assign each and every user id with a random number between 1 to 44.

Related

Mongo find an array inside a collection and get only that data

How can I get only the data from menus which _id is 1?
I've tried:
db.collection("restaurants")
.find({ name : String(name), "menus._id": Number(id)} )
.toArray(function (err, result) {
But I still get the full result from restaurant and not only the menu
you have to use projection to retrieve only the menus field.
db.collection("restaurants").find( { name: String(name), "menus._id": Number(id) }, { _id: 0, menus: 1 } ).toArray( function(err,result) { } );
with or without projection the _id field is returned by default, you have to turn it off by setting the _id field to 0. 0 means don't show the value of this field, while 1 does the opposite

MySQL JSON_EXTRACT wildcard field name matching

I have following JSON data in MySQL JSON FIELD
{
"Session0":[
{
"r_type":"main",
"r_flag":"other"
},
{
"r_type":"sub",
"r_flag":"kl"
}
],
"Session1":[
{
"r_type":"up",
"r_flag":"p2"
},
{
"r_type":"id",
"r_flag":"mb"
}
],
"Session2":[
{
"r_type":"main",
"r_flag":"p2"
},
{
"r_type":"id",
"r_flag":"mb"
}
]
}
Now, I wish to search ALL sessions where r_type="main". The session number can vary, hence I can not use a OR query. So, I need something like: where
JSON_EXTRACT(field,"$.Session**[*].r_type")="main"
But this does not seem to work. I need to be able to use wildcard in the property's name and then search an array for a property inside it. How do I do that?
Following work's, but that limits our ability to have unlimited Sessions numbers.
SELECT field->"$.Session1[*].r_type" from table

D3 Loading in CSV file then using only specific columns

I've had a hard time getting two columns from a CSV file with which I am planning on building a basic bar chart. I was planning on getting 2 arrays (one for each column) within one array that I would use as such to build a bar chart. Just getting started with D3, as you can tell.
Currently loading the data in gets me an array of objects, which is then a mess to get two columns of key-value pairs. I'm not sure my thinking is correct...
I see this similar question:
d3 - load two specific columns from csv file
But how would I use selections and enter() to accomplish my goal?
You can't load just 2 columns of a bigger CSV, but you can load the whole thing and extract the columns you want.
Say your csv is like this:
col1,col2,col3,col4
aaa1,aaa2,aaa3,aaa4
bbb1,bbb2,bbb3,bbb4
ccc1,ccc2,ccc3,ccc4
And you load it with
csv('my.csv', function(err, data) {
console.log(data)
/*
output:
[
{ col1:'aaa1', col2:'aaa2', col3:'aaa3', col4:'aaa4' },
{ col1:'bbb1', col2:'bbb2', col3:'bbb3', col4:'bbb4' },
{ col1:'ccc1', col2:'ccc2', col3:'ccc3', col4:'ccc4' }
]
*/
})
If you only want col2 and col3 (and you don't want to simply leave the other columns' data in there, which shouldn't be an issue anyway), you can do this:
var cols2and3 = data.map(function(d) {
return {
col2: d.col2,
col3: d.col3
}
});
console.log(cols2and3)
/*
output:
[
{ col2:'aaa2', col3:'aaa3' },
{ col2:'bbb2', col3:'bbb3' },
{ col2:'ccc2', col3:'ccc3' }
]
*/
I.e. the above code produced a new array of objects with only two props per object.
If you want just an array of values per column — not objects with both columns' values — you can:
var col2data = data.map(function(d) { return d.col2 }
var col3data = data.map(function(d) { return d.col3 }
console.log(col2) // outputs: ['aaa2', 'bbb2', 'ccc2']

How to remove an attribute from list of json object in mongo shell? [duplicate]

This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Remove field found in any mongodb array
(2 answers)
Closed 3 years ago.
I have below document in MongoDB(2.4.5)
{
"_id" : 235399,
"casts" : {
"crew" : [
{
"_id" : 1186343,
"withBase" : true,
"department" : "Directing",
"job" : "Director",
"name" : "Connie Rasinski"
},
{
"_id" : 86342,
"withBase" : true
}
]
},
"likes" : 0,
"rating" : 0,
"rating_count" : 0,
"release_date" : "1955-11-11"
}
I want to remove withBase filed from array elements inside casts.crew ..
I tried this
db.coll.update({_id:235399},{$unset: { "casts.crew.withBase" : 1 } },false,true)
nothing changed.
And tried this..
db.coll.update({_id:235399},{$unset: { "casts.crew" : { $elemMatch: { "withBase": 1 } } } },false,true)
it removed entire crew array from the document.
Can someone please provide me the right query?
You can use the new positional identifier to update multiple elements in array in 3.6.
Something like
db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} )
$[] removes all the withBase property from the crews array. It acts as a placeholder for updating all elements in array.
Use multi true to affect multiple documents.
Sorry to disappoint you, but your answer
db.coll.update({
_id:235399,
"casts.crew.withBase": {$exists: true}
},{
$unset: {
"casts.crew.$.withBase" : true
}
},false,true)
is not correct. Actually it will remove the value, BUT only from the first occurrence of the subdocument, because of the way positional operator works:
the positional $ operator acts as a placeholder for the first element
that matches the query document
You also can not use $unset (as you tried before) because it can not work on arrays (and are you basically trying to remove a key from a document from the array). You also can not remove it with $pull, because pull removes all the array, not just a field of it.
Therefore as far as I know you can not do this with a simple operator. So the last resort is doing $find and then forEach with save. You can see how to do this in my answer here. In your case you need to have another loop in forEach function to iterate through array and to delete a key. I hope that you will be able to modify it. If no, I will try to help you.
P.S. If someone looks a way to do this - here is Sandra's function
db.coll.find({_id:235399}).forEach( function(doc) {
var arr = doc.casts.crew;
var length = arr.length;
for (var i = 0; i < length; i++) {
delete arr[i]["withBase"];
}
db.coll.save(doc);
});
I found a way to unset this lists without having to pull up the object (meaning, just doing an update), it's pretty hackish but if you have a huge database it will make the deal:
db.coll.update({},{$unset: {"casts.crew.0.withBase" : 1, "casts.crew.1.withBase" : 1} }, {multi: 1})
In other words, you have to calculate how many objects there can be in any of your documents list and add those numbers explicitly, in this case as {casts.crew.NUMBER.withBase: 1}.
Also, to count the longest array in a mongodb object, an aggregate can be done, something like this:
db.coll.aggregate( [ { $unwind : "$casts.crew" }, { $group : { _id : "$_id", len : { $sum : 1 } } }, { $sort : { len : -1 } }, { $limit : 1 } ], {allowDiskUse: true} )
Just want to emphasize that this is not a pretty solution but is way faster than fetching and saving.

MongoDB find() to return the sub document when a (field,value) is matched

This is a single collection which has 2 json files. I am searching for a particular field: value in an object and the entire sub document must be returned in case of a match ( That particular sub document from the collection must be returned out of the 2 sub documents in the following collection). Thanks in advance.
{
"clinical_study": {
"#rank": "379",
"#comment": [],
"required_header": {
"download_date": "ClinicalTrials.gov processed this data on March 18, 2015",
"link_text": "Link to the current ClinicalTrials.gov record.",
"url": "http://clinicaltrials.gov/show/NCT00000738"
},
"id_info": {
"org_study_id": "ACTG 162",
"secondary_id": "11137",
"nct_id": "NCT00000738"
},
"brief_title": "Randomized, Double-Blind, Placebo-Controlled Trial of Nimodipine for the Neurological Manifestations of HIV-1",
"official_title": "Randomized, Double-Blind, Placebo-Controlled Trial of Nimodipine for the Neurological Manifestations of HIV-1",
}
{
"clinical_study": {
"#rank": "381",
"#comment": [],
"required_header": {
"download_date": "ClinicalTrials.gov processed this data on March 18, 2015",
"link_text": "Link to the current ClinicalTrials.gov record.",
"url": "http://clinicaltrials.gov/show/NCT00001292"
},
"id_info": {
"org_study_id": "920106",
"secondary_id": "92-C-0106",
"nct_id": "NCT00001292"
},
"brief_title": "Study of Scaling Disorders and Other Inherited Skin Diseases",
"official_title": "Clinical and Genetic Studies of the Scaling Disorders and Other Selected Genodermatoses",
}
Your example documents are malformed - right now both clinical_study keys are part of the same object, and that object is missing a closing }. I assume you want them to be two separate documents, although you call them subdocuments. It doesn't make sense to have them be subdocuments of a document if they are both named under the same key. You cannot save the document that way, and in the mongo shell it will silently replace the first instance of the key with the second:
> var x = { "a" : 1, "a" : 2 }
> x
{ "a" : 2 }
If you just want to return the clinical_study part of the document when you match on clinical_study.#rank, use projection:
db.test.find({ "clinical_study.#rank" : "379" }, { "clinical_study" : 1, "_id" : 0 })
If instead you meant for the clinical_study documents to be elements of an array inside a larger document, then use $. Here, clinical_study is now the name of an array field which has as its elements the two values of the clinical_study key in your non-documents:
db.test.find({ "clinical_study.#rank" : "379" }, { "_id" : 0, "clinical_study.$" : 1 })