MongoDB returns all records even after specifying fields - mongodb

> db.checklistDB.find({},{title:1, _id:0})
{ "title" : "Untitled Checklist" }
{ }
{ }
{ }
{ }
{ }
> db.checklistDB.find({},{title:1})
{ "title" : "Untitled Checklist", "_id" : "4FaJcAkzAY3Geyggm" }
{ "_id" : "3imNYy8SPcRDjLcqz" }
{ "_id" : "977fPtvEn7hiStqzp" }
{ "_id" : "QcAEMnr6R7qfaWFR8" }
{ "_id" : "eEsmKMdQGYKqnhTNB" }
{ "_id" : "cL6R8qxwWhvTr2kmy" }
Hi Guys,
As you can see from the above, I rand 2 commands:
db.checklistDB.find( {} , { title : 1 } ) and
*db.checklistDB.find( {} , { title : 1 , _id : 0} )
Both queries returns 6 records which is all the records that exists in the database. I would imagine that it will only return records that have "title" as a field. Is there something I'm doing wrong?

Second argument for find is projection. In your case it looks for title field inside document, and if it doesn’t exist returns none. If you want to filter documents you should use query like this:
db.checklistDB.find({title: {$exists: true}}, {title:1, _id:0})
EDIT
If you take your query:
db.checklistDB.find({}, {title:1, _id:0})
It translates to: retrieve all documents ({} as query argument) and for every document give me title if exist or default value (none) if it doesn’t ({title:1, _id:0} as projection argument). Projection argument is used only to transform not to filter documents.

Related

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"
}
}
}
}
>

Mongo DB , how select all documents in match query?

FOR getting all documents, what I write instead of XXXX.
I want to get all values without a criterion. I must use aggregate and match function.
payload.sla.customer.externalId variable is string.
db.collection.aggregate ( [
{ "$match" : {
"payload.sla.customer.externalId" : XXXX
}}
])
collection sample example
{
"_id" : ObjectId("5b929a84aff3dc185627add1"),
"payload" : {
"sla" : {
"customer" : {
"externalId" : "140689900",
}
}
}
}

Use MongoDB _id field as composite field with multiple fields

Since every collection in mongodb has a default index on the _id column, I wanted to leverage it for my scenario as below.
I have my collection as below,
{
"_id":{
"timestamp" : ISODate("2016-08-24T23:22:20.201Z"),
"departmentname" : "sales",
"city":"NJ"
}
//Other fields in my collection
}
With this structure I am able to query as below,
db.getCollection('test').find(
{
"_id" : {
"timestamp" : ISODate("2016-08-21T23:22:20.201Z"),
"departmentname" : "sales",
"city":"NJ"
}
}
)
But, when I query by one or more fields in which are part of _id column as below,
db.getCollection('test').find(
{
"_id" : {
"timestamp" : ISODate("2016-08-21T23:22:20.201Z")
}
}
)
(OR)
db.getCollection('test').find(
{
"_id" : {
"departmentname" : "sales"
}
}
)
(OR)
db.getCollection('test').find(
{
"_id" : {
"departmentname" : "sales",
"city":"NJ"
}
}
)
I do not see any documents returned
When I checked with .explain() I see that it has used Index but did not find any documents.
Also, I would like to do date range queries on timestamp field along with query on one or more fields in the _id column like below,
db.getCollection('test').find(
{
"_id.timestamp" : {
"$gte": ISODate("2011-08-21T23:22:20.201Z")
},
"_id.departmentname" : "sales"
}
)
But, I do not see any documents returned. When I run .explain() I see it has used colscan and not index.
Can someone help me on the right way to query by one or more fields on my _id column.
Thanks,
Sri
You can try following query, in first case:-
db.getCollection('test').find(
{
"_id.timestamp" : ISODate("2016-08-21T23:22:20.201Z")
})
And this for multiple fields:
db.getCollection('test').find(
{
"_id.timestamp" : ISODate("2016-08-21T23:22:20.201Z"),
"_id.departmentname" : "sales",
})

Nested mongo query

Here is what the data looks like:
{
"_id" : {
"item" : "1",
"state" : "something"
},
"things" : {
"ordered" : 2,
"cost" : 123
}
}
I try to query for all doc of item 1, there are many state for that item. I know i can get that record using db.orders.find({_id:{item:"1", state: "something"}}). But I would like to get all states I try something like db.orders.find({_id:{item:"1", state: {$exists: true}}})
But that doesn't seem to work. What am i doing wrong?
If you want to get the list of all the different states you could use.
db.orders.distinct("_id.state");
If you want to get the list of all the states in your collection
db.orders.find({}, {"_id.state": 1});
I really want to get the things.cost for all the states for a given
item
db.orders.aggregate([
{ $group : {
_id : { item : "$_id.item" , state : "$_id.state"},
cost: { $push : "$things.cost" }
}
}
]);
If you want the sum instead of the elements of the group by use $sum instead of $push
How do i get for certain item?
db.orders.aggregate([
{ $match : { "_id.item" : "YOUR_ID" }},
{ $group : {
_id : { item : "$_id.item" , state : "$_id.state"},
cost: { $push : "$things.cost" }
}
}
]);

Update a Map value document value using Mongo

I have a document like myPortCollection
{
"_id" : ObjectId("55efce10f027b1ca77deffaa"),
"_class" : "myTest",
"deviceIp" : "10.115.75.77",
"ports" : {
"1/1/x1" : {
"portId" : "1/1/x1",
healthState":"Green"
I tried to update
db.myPortCollection.update({
{ deviceIp:"10.115.75.77"},
{ "chassis.ports.1/1/x10.rtId":"1/1/x10" },
{ $set: { "chassis.ports.1/1/x10.healthState" : "Red" }
})
But I am getting error that attribute names mentioned is wrong,.Please help in specifying the syntax properly for embedded map document update.
The "query" portion is wrong as you have split conditions into two documents. It should be this:
db.myPortCollection.update(
{
"deviceIp":"10.115.75.77",
"chassis.ports.1/1/x10.rtId":"1/1/x10"
},
{ "$set": { "chassis.ports.1/1/x10.healthState" : "Red" } }
)
And as long as the query then matches ( valid data not shown in your question ) then the specified field will be set or added.