Changing strings in mongodb collection to uppercase - mongodb

I've searched a lot but still can't find (or understand) the answer. I have a collection in my mongodb database that is called "btest". Inside of that collection I have a list of randomly generated strings (from 1000 to 1000000) that look something like this:
> db.btest.find()
{ "_id" : ObjectId("5818ed42c33b12a7c902cd34"), "0" : 1, "wgickjkwxfimleot" : "r
scjuvarvmvuheom" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd35"), "0" : 2, "wgickjkwxfimleot" : "t
gdqnegjscsmnjsi" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd36"), "0" : 4, "wgickjkwxfimleot" : "d
qjvndthelmtqknj" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd37"), "0" : 5, "wgickjkwxfimleot" : "u
qtmbuhgwxntcixh" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd38"), "0" : 6, "wgickjkwxfimleot" : "i
rguwjvectjvimjk" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd39"), "0" : 7, "wgickjkwxfimleot" : "n
sggjpodfvebjumk" }
{ "_id" : ObjectId("5818ed42c33b12a7c902cd3a"), "0" : 8, "wgickjkwxfimleot" : "a
wvjtlxtoqwpdltp" }
I imported these using this command:
mongoimport -d ee_db -c btest --type csv --file "C:\Users\USER\Desktop\Random\projekty java\ee_bulk_insert\src\10000.csv" --headerline
What I want to do is to change all the strings in this collection to uppercase letters. In MySQL I've done the same thing with the "SELECT UCASE(row) FROM btest;" command.
How to achieve the same result in MongoDB? Thanks for all the answers.

You can use an aggregation with a $project using $toUpper to convert string to uppercase and then write the results in a new collection with $out :
db.btest.aggregate(
[{
$project: {
"0": 1,
"wgickjkwxfimleot": { $toUpper: "$wgickjkwxfimleot" }
}
}, {
$out: "results"
}]
)

Related

How to create a compound index for speicifc documents in mongodb

I'm running MongoDB 4.2, see below how my documents look like:
{
"_id" : ObjectId("61e8e5b72e74b7fc3e16b632"),
"1" : 2,
"age_upon_outcome" : "1 year",
"animal_id" : "A725717",
"animal_type" : "Cat",
"breed" : "Domestic Shorthair Mix",
"color" : "Silver Tabby",
"date_of_birth" : "2015-05-02",
"datetime" : "2016-05-06 10:49:00",
"monthyear" : "2016-05-06T10:49:00",
"name" : "",
"outcome_subtype" : "SCRP",
"outcome_type" : "Transfer",
"sex_upon_outcome" : "Spayed Female",
"location_lat" : 30.6525984560228,
"location_long" : -97.7419963476444,
"age_upon_outcome_in_weeks" : 52.9215277777778
}
Bottom line is that I need to create a compound index that will improve the performance of queries looking for breeds that have an “outcome_type” of “Transfer”, and I'm not sure of how to narrow down the command below to only documents with outcome_type=Transfer
db.collection.createIndex( { breed: 1 } )
Would be this one:
db.collection.createIndex(
{ breed: 1 },
{ partialFilterExpression: { outcome_type: 'Transfer' } }
)

Update a json document in a mongodb database

I'm trying to update an existing document in a MongoDb. There are many explanations how to do this if you want to update or add key/value pairs on the first level. But in my use-case, I need to create with the first updateOne (with upsert option set) a document with the following structure:
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
}
}
}
}
In the second command, I need to add - in the same document - a "meas2" field at the level of "meas1". My desired output is:
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
},
"meas2" : {
"data" : "foo"
}
}
}
}
I played with statements like
updateOne({"_id":"1234"},{$set:{"raw":{"meas":{"meas2":{"data":"foo"}}}}}, {"upsert":true})
and also with $push, both variants with insert - here only the document and also insertOne, but nothing produces the desired output. Is there a MongoDb expert who could give a hint ? ... I'm sure this functionality exists... Thanks in advance!
When you update {$set: {"raw":{"meas":{"meas2":{"data":"foo"}}}} you're not adding "mesa2" to "meas" but rather you're overriting "raw" completely.
In order to change / add one field in a document refer to it with dot notations.
The command you want is updateOne({"_id": "1234"}, {$set: {"raw.meas.mesa2": { "data" : "foo" }}}, {"upsert":"true"})
You need to understand the below concept first
Set Fields in Embedded Documents, with details document check at official documentation of mongo
For your problem, just look at the below execution on the mongo shell:
> db.st4.insert({
... "_id" : "1234",
... "raw" : {
... "meas" : {
... "meas1" : {
... "data" : "blabla"
... }
... }
... }
... })
WriteResult({ "nInserted" : 1 })
> db.st4.find()
{ "_id" : "1234", "raw" : { "meas" : { "meas1" : { "data" : "blabla" } } } }
>
> // Below query will replace the raw document with {"meas":{"meas2":{"data":"foo"}}}, will not add
> //db.st4.updateOne({"_id":"1234"},{$set:{"raw":{"meas":{"meas2":{"data":"foo"}}}}}, {"upsert":true})
>// By using the dot operator, you actually write the values inside the documents i.e you are replacing or adding at raw.meas.mesa2 i.e inside the document of mesa2.
> db.st4.updateOne({"_id":"1234"},{$set: {"raw.meas.mesa2": { "data" : "foo" }}}, {"upsert":"true"})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.st4.find().pretty()
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
},
"mesa2" : {
"data" : "foo"
}
}
}
}
>

Positional operator and field limitation

In a find query projection, fields I specify after the positional operator are ignored and the whole document is always returned.
'myArray.$.myField' : 1 behave exactly like 'myArray.$' : 1
the positional operator selects the right document. But this document is quite big. I would like to project only 1 field from it.
Exemple:
db.getCollection('match').find({"participantsData.id" : 0001}, { 'participantsData.$.id': 1, })
here the response I have
{
"_id" : "myid",
"matchCreation" : 1463916465614,
"participantsData" : [
{
"id" : 0001,
"plenty" : "of",
"other" : "fields",
"and" : "subdocuments..."
}
]
}
This is what I want
{
"_id" : "myid",
"matchCreation" : 1463916465614,
"participantsData" : [
{
"id" : 0001
}
]
}
Is it possible with mongo?
Yes it can be done in mongo
Please try the below query
db.getCollection('match').find(
{"participantsData.id" : 0001},
{"participantsData.id": 1, "matchCreation": 1 })
This will give you the below result
{
"_id" : "myid",
"matchCreation" : 1463916465614,
"participantsData" : [
{
"id" : 1
}
]
}

MongoDB fields limitation in array [duplicate]

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 8 years ago.
I am looking for a way - and dont even now if this is possible - just to return a part of a list saved in mongodb.
Lets have a look in my currently document:
{
_id : 'MyId',
name : 'a string',
conversations : [
{
user : 'Mike',
input : 'Some input'
},
{
user : 'Stephano',
input : 'some other input'
}
]
}
What I now want to do is smth like this:
var myOutput;
myOutput = db.my_collection.find(
{
_id : 'MyId',
'conversations.user' : 'Mike'
}, {
_id : 1,
name : 1,
conversations : {
$where : {
user : 'Mike'
}
}
});
Goal is it just to get back the conversation array item where user has the value Mike.
Is this still possible in MongoDB ? didn't found any reference in the documentation for the field limitations in mongoDB.
Use the $ positional operator in a projection:
> db.my_collection.find({ "_id" : "MyId", "conversations.user" : "Mike" },
{ "_id" : 1, "name" : 1, "conversations.$" : 1 })
{
"_id" : 'MyId',
"name" : 'a string',
"conversations" : [
{ "user" : 'Mike', "input" : 'Some input' }
]
}
This projects only first matching array element.
Are you aware of the aggregation pipeline?
db.my_collection.aggregate([
{ "$match": { "_id": "MyId"}}, { "$unwind": "$conversations"},
{ "$match": {"conversations.user": "Mike"}}
])
Output
{
"_id" : "MyId",
"name" : "a string",
"conversations" :
{
"user" : "Mike",
"input" : "Some input"
}
}

How to update particular array element in MongoDB

I am newbie in MongoDB. I have stored data inside mongoDB in below format
"_id" : ObjectId("51d5725c7be2c20819ac8a22"),
"chrom" : "chr22",
"pos" : 17060409,
"information" : [
{
"name" : "Category",
"value" : "3"
},
{
"name" : "INDEL",
"value" : "INDEL"
},
{
"name" : "DP",
"value" : "31"
},
{
"name" : "FORMAT",
"value" : "GT:PL:GQ"
},
{
"name" : "PV4",
"value" : "1,0.21,0.00096,1"
}
],
"sampleID" : "Job1373964150558382243283"
I want to update the value to 11 which has the name as Category.
I have tried below query:
db.VariantEntries.update({$and:[ { "pos" : 117199533} , { "sampleID" : "Job1373964150558382243283"},{"information.name":"Category"}]},{$set:{'information.value':'11'}})
but Mongo replies
can't append to array using string field name [value]
How one can form a query which will update the particular value?
You can use the $ positional operator to identify the first array element to match the query in the update like this:
db.VariantEntries.update({
"pos": 17060409,
"sampleID": "Job1373964150558382243283",
"information.name":"Category"
},{
$set:{'information.$.value':'11'}
})
In MongoDB you can't adress array values this way. So you should change your schema design to:
"information" : {
'category' : 3,
'INDEL' : INDEL
...
}
Then you can adress the single fields in your query:
db.VariantEntries.update(
{
{"pos" : 117199533} ,
{"sampleID" : "Job1373964150558382243283"},
{"information.category":3}
},
{
$set:{'information.category':'11'}
}
)