I have following collection with me from MongoDB:
{ "results": [
{
"isExist": true,
"isJourneyEnd": true,
"objectId": "9WtZcxWttk",
"sentTo": [
"JeLRe4yH9R"
],
},
{
"isExist": false,
"isJourneyEnd": true,
"objectId": "9WtZcxWtul",
"sentTo": [
"JeLRe4y9HU"
],
}
]}
In actual, there are many entries in this collection, I've just mentioned two.
If I want to write a query for following statement:
"Print element of array whose isExist is true".
I would like to have some guidance over this, as I am new to MongoDB.
Try this :
db.collection.find({isExist: true});
Related
I've this complex structure in a project I'm working on, and I can't find a way to bulk add some values in the "parametri" array.
Here is an example document:
My goal is to add some values to "parametri" array that is inside the Object at position 1 of the array "protocolli".
In mongoDB Compass I can do a select using "'protocolli.nome': 'protocollo-2'", so I've tried the following code (the project is written in TS, uses a NestJs backend and Mongoose to communicate with MongoDB):
this.model.updateMany(
{ 'protocolli.nome': ProtocolloAlert.PROTOCOLLO_2 },
{
$push: {
'protocolli.parametri': {
$each: [
TipoParametro.FAT_MASS,
TipoParametro.DISTANCE,
TipoParametro.MUSCLE_MASS,
TipoParametro.STEPS,
TipoParametro.CALORIES,
TipoParametro.MINUTES,
],
},
},
},
{ multi: true }
)
I've already tried $push, $addToSet, $set with no positive result..
Using this method, I've the following error:
MongoError: Cannot create field 'parametri' in element {protocolli: [ { nome: "protocollo-1", parametri: [ "temp", "spo2", "hr", "sys" ], descrizione: "Attivazione alert in control room, inserimento nei log degli alert in corso, salvataggio nella scheda alert del paziente" }, { nome: "protocollo-2", parametri: [ "dya", "pulse", "fr", "pef", "fev1", "fvc", "fev1fvc", "etco2", "freqRes", "glucose", "weight", "height", "bmi", "bodyFat", "hba1c", "totCh", "triglycerides", "hdl", "ldl" ], descrizione: "Salvataggio nella scheda alert del paziente" } ]}
at Function.create (C:....\node_modules\mongodb\lib\core\error.js:57:12)
Thanks in advance.
I have a documents with the following structure:
{
_id: ObjectId(),
"subjects": [
{
"name": "math",
"first_try": {
"passed": true
},
"second_try": {
"passed": false
},
"third_try": {
"passed": false
},
"fourth_try": {
"passed": false
}
}
]
}
There are a couple of such subjects there.
Please don't suggest to change data structure, etc. - it's a fake data structure created just for this question (can't share original names, but structure is the same).
For each of these subjects I have always these 4 keys: "first_try", "second_try", ..., "fourth_try". Some of them are "passed", some - not.
For each subject I want to set first_try.passed: true if there weren't other passed tries.If for example third_try.passed:true I shouldn't update first_try.
I was trying to proceed with some aggregate conditions including elemMatch to find items for update, but it looks awful and didn't work as I expect.
Is it possible to handle this case with single updateMany query?
You can use arrayFilters:
collection.updateMany({},
{$set: {"subjects.$[element].first_try.passed": true}},
{arrayFilters: [{
"element.first_try.passed":false,
"element.second_try.passed":false,
"element.third_try.passed":false,
"element.fourth_try.passed":false}]})
I have a user document that looks like this:
{
"userId": "249869823570",
"name": "john",
"country": "usa",
"active": true,
"serviceProviders": [
{
"serviceProvidersId": "897892893",
"serviceProvidersName": "AT&T",
"active": true,
"serviceProviderContactPerson": []
},
{
"serviceProvidersId": "82589628569",
"serviceProvidersName": "T-Mobile",
"active": true,
"serviceProviderContactPerson": []
}
]
}
and I want to create 3 methods to insert/update/delete a serviceProviderContactPerson. my dilema is, my main document have array of serviceProviders, and a serviceProvider have a list of serviceProviderContactPerson...what would be the best practice in mongo to work this?
serviceProviderContactPerson document will look like this:
{
"contactId": "873498798",
"name": "Mark",
"email": "mark#tmobile.com",
"phone": "917-475-4637"
}
You can use update to perform all operations in 3.6.
Insert a new array element where serviceProvidersId = "897892893"
db.colname.update(
{"serviceProviders.serviceProvidersId":"897892893"},
{$push: {"serviceProviders.$.serviceProviderContactPerson":serviceProviderContactPersonDoc}}
)
Update phone where serviceProvidersId = "897892893" and contactId = "873498798"
db.colname.update(
{},
{$set: {"serviceProviders.$[sp].serviceProviderContactPerson.$[spc].phone":phone value}},
{arrayFilters:[{"sp.serviceProvidersId":"897892893"}, {"spc.contactId":"873498798"}]}
)
Delete array element where serviceProvidersId = "897892893" and contactId = "873498798"
db.colname.update(
{},
{$pull: {"serviceProviders.$[sp].serviceProviderContactPerson":{"contactId":"873498798"}}},
{arrayFilters:[{"sp.serviceProvidersId":"897892893"}]}
)
How do I find course_id in meteor.users then insert/update/upsert my data into "classes" (an empty array)?
if cant find course_id then insert a new array, if i can then i update the array with new classes_id.
Empty classes array:
{
"_id": "RoFFcaAfXBeR2napZ",
"emails": [
{
"address": "tong#gmail.com",
"verified": false
}
],
"classes": [],
"courses": [
"qwmZdgQbrZ3rmHdN8"
]
}
Insert new array to classes if i cant find course_id:
{
"_id": "RoFFcaAfXBeR2napZ",
"emails": [
{
"address": "tong#gmail.com",
"verified": false
}
],
"classes": [
{
"course_id": "svesvinfdsgrvnekuktndvsk",
"classes_id": ["myclass1"]
},
],
"courses": [
"qwmZdgQbrZ3rmHdN8"
]
}
Add myclass2 to classes_id if i can find course_id
{
"_id": "RoFFcaAfXBeR2napZ",
"emails": [
{
"address": "tong#gmail.com",
"verified": false
}
],
"classes": [
{
"course_id": "svesvinfdsgrvnekuktndvsk",
"classes_id": ["myclass1", "myclass2"]
},
],
"courses": [
"qwmZdgQbrZ3rmHdN8"
]
}
To find the record that has the course ID in question: Meteor.users.find({"courses": yourVariableHoldingTheId}) is an example query. This assumes that your publication has the courses field on it (more on publishing Users stackoverflow and Meteor.
From that query, you'll now have the Cursor of Users that meet your criteria. Iterate over the users and treat them as normal JS objects - check your criteria and either push to the classes subdocument, or push to the classes.$.classesId.
Pushing to classes Meteor.users.update({_id: "RoFFcaAfXBeR2napZ"}, {$push: {'classes': {'course_id': 'yourGibberishHere', 'classes_id': ['test']}}});
Pushing to the classes_id Meteor.users.update({"classes.course_id": "svesvinfdsgrvnekuktndvsk"}, {$push: {"classes.$.classes_id": "myclass3"}}); tested on Mongo 3.2, your mileage may vary in meteor (2.6 or 3.2, if you're using external mongo). Older commentary points to x.$.y not working in meteor/mongo $push, not sure if this is still the case.
If any of these fail, you can manipulate the object returned from the find and update it or subdocuments thereof using more accessible calls
I've searched the docs and web throughly but cannot find any solution for this seemingly trivial problem. Let's say we have a collection called "states". The states collection has a document that looks like this:
{
'name': 'New York',
'towns': [
{
'name': 'Town A',
'buildings':[
{
'name': 'Town Hall',
'open_days': [False, True, True, True, True, True, False],
},
{
'name': 'Fire Department',
'open_days': [True, True, True, True, True, True, True],
},
{
'name': 'Car Dealership',
'open_days': [False, True, True, True, True, True, True],
}
]
},
{
'name': 'Town B',
'buildings':[
{
'name': 'Town Hall',
'open_days': [False, True, True, True, True, True, False],
},
{
'name': 'Police Department',
'open_days': [True, True, True, True, True, True, True],
},
{
'name': 'Karate Dojo',
'open_days': [False, True, False, True, False, True, False],
}
]
}
]
}
In this data, open_days represents whether a building is open or closed on a particular day of the week (index 0 being Sunday for example).
I just want to query the data to pull up all the buildings that are open on Sunday (index 0).
I've tried several odd syntaxes to no avail, is there an easy solution to this? If it matters, I am querying using PyMongo.
It actually depends. First of all there are a few ways to restructure your data a little bit to make it more easy to query and to extract. You don't have to restructure it at all, but if you can I think it would be beneficial.
Some refactoring suggestions:
First of all you might want to split this single large document into multiple documents. Just take out documents from array towns and make each one a standalone document in your collection. Add state name to each. Embedding docs in Mongo is a good idea, but it seems to me that this is a bit over too much. I would even go further extracting each building into a top level document. The reasons for this are: you might not be able to fit all buildings in a large city into a single document (size limit 16Mb). Even if you are able to fit all buildings into a single document your queries will be quite inefficient if you want to select only small part of that document.
Change your array to hold integers corresponding to indexes of weekdays, i.e. Sunday == 0, etc. This will make it simpler and more efficient to query.
So your data would look this way:
{
"stateName": "New York",
"townName": "Town A",
"buildingName": "Town Hall",
"open_days": [1, 2, 3, 4, 5]
}
Now you can find a building in a city that's open on Monday (1):
db.buildings.find({"stateName": "New York", "townName": "Town A", "open_days": 1});
If you don't want to restructure your data take a look at $elemMatch here which projects matched element of an array. You can also take a look at $ here. However, both these operators do not solve your problem because they return first matched element in the array.
You can also use aggregation framework, but you'll be limited to number of results that fit in a single doc (16Mb), won't be able to have a cursor to results, it will be slower and it's over complicated for what you want to do.
What you could use here is aggregation framework. You will find lots of nice examples on aggregation framework in MongoDB docs - Aggregation
What you could be interested in in particular would be $unwind pipeline operator which peels off the elements of an array individually, and returns a stream of documents. $unwind returns one document for every member of the unwound array within every source document.
Here is an example, I hope it provides what you expect it to do:
> db.collection.aggregate(
... { $match : { "towns.buildings.open_days.0" : true }},
... { $unwind : "$towns"},
... { $unwind : "$towns.buildings"},
... { $match : { "towns.buildings.open_days.0" : true }}
... )
{
"result" : [
{
"_id" : ObjectId("52e5ba3beb849fd797d10839"),
"name" : "New York",
"towns" : {
"name" : "Town A",
"buildings" : {
"name" : "Fire Department",
"open_days" : [
true,
true,
true,
true,
true,
true,
true
]
}
}
},
{
"_id" : ObjectId("52e5ba3beb849fd797d10839"),
"name" : "New York",
"towns" : {
"name" : "Town B",
"buildings" : {
"name" : "Police Department",
"open_days" : [
true,
true,
true,
true,
true,
true,
true
]
}
}
}
],
"ok" : 1
}