How to show specific column in mongo db collection - mongodb

I tried to show particular columns in mongodb colletion.but its not working.how to show particular columnns.
user_collection
[{
"user_name":"hari",
"user_password":"123456"
}]
find_query
db.use_collection.find({},{projection:{user_name:1}})
I got output
[{
"user_name":"hari",
"user_password":"123456"
}]
Excepted output
[{
"user_name":"hari",
}]

Try:
db.use_collection.find({}, {user_name:1, _id: 0 })
In that way you get the field user_name and exclude the _id.
Extra info:
project fields and project fields excluding the id
With aggregate:
db.use_collection.aggregate( [ { $project : { _id: 0, user_name : 1 } } ] )

You can try this
Mongo query:
db.users.aggregate([
{
"$project":
{
"_id": 0,
"first_name": 1,
}
}
])
Or in ruby (Mongoid)
User.collection.aggregate(
[
"$project":
{
"_id": 0,
"first_name": 1,
}
]
)
If you try to inspect the record, you can convert it into an array first (e.g. User.collection.aggregate(...).to_a)
You can use the official mongodb reference when writing in Mongoid, usually you just need to use double quote on the property name on the left hand side, to make it work on Mongoid.

Try:
db.use_collection.find({}, {user_password:0, _id: 0 ,user_name:1 })

Related

Group and Combine Text Fields Using Pymongo

I have a collection of user reviews and I'm trying to combine all the reviews by user so I can run some NLP analysis on them. This feels like it should be easy, but I'm missing something with how Mongo treats strings.
My documents look like this:
{'_id': ObjectId('57e079d3e3874f12ad721f70'),
'atmosphere': 5,
'review_id': 63,
'dedication': 3,
'orgName': 'Some Organization',
'enabled': True,
'accessibility': 3,
'efficiency': 3,
'orgId': '57e05e0de3874f121d516616',
'user': '5809f2c0bc0a53eb49eac583',
'date': '10/20/15 0:00',
'quality': 3,
'orgId_orig': 1098,
'description': 'Here is some sample text'
}
I've tried this:
agg_result = revs.aggregate( [
{ "$group": { "_id": "$user", "mergedText": { "$mergeObjects": "$description" } } }
])
for i in agg_result:
print(i)
But I'm getting this error:
OperationFailure: $mergeObjects requires object inputs, but input "Here is some sample text" is of type string
My expected output would be
{
'userId1':{'mergedText':'joined descriptions from this user'},
'userId2':{'mergedText':'this users descriptions'},
'userId3':{'mergedText':'all descriptions from this user'}
}
where the various userIds are Mongo ObjectIds from the 'user' field.
I'm brand new to Mongo and this has been tripping me up for awhile. Thank you.
try this , merge object needs objectbut your description is string you could push in array
agg_result = revs.aggregate( [
{ "$group": { "_id": "$user", "mergedText": { "$push": "$description" } } }
])
for i in agg_result:
print(i)

Can't remove object in array using Mongoose

This has been extensively covered here, but none of the solutions seems to be working for me. I'm attempting to remove an object from an array using that object's id. Currently, my Schema is:
const scheduleSchema = new Schema({
//unrelated
_id: ObjectId
shifts: [
{
_id: Types.ObjectId,
name: String,
shift_start: Date,
shift_end: Date,
},
],
});
I've tried almost every variation of something like this:
.findOneAndUpdate(
{ _id: req.params.id },
{
$pull: {
shifts: { _id: new Types.ObjectId(req.params.id) },
},
}
);
Database:
Database Format
Within these variations, the usual response I've gotten has been either an empty array or null.
I was able slightly find a way around this and accomplish the deletion by utilizing the main _id of the Schema (instead of the nested one:
.findOneAndUpdate(
{ _id: <main _id> },
{ $pull: { shifts: { _id: new Types.ObjectId(<nested _id>) } } },
{ new: true }
);
But I was hoping to figure out a way to do this by just using the nested _id. Any suggestions?
The problem you are having currently is you are using the same _id.
Using mongo, update method allows three objects: query, update and options.
query object is the object into collection which will be updated.
update is the action to do into the object (add, change value...).
options different options to add.
Then, assuming you have this collection:
[
{
"_id": 1,
"shifts": [
{
"_id": 2
},
{
"_id": 3
}
]
}
]
If you try to look for a document which _id is 2, obviously response will be empty (example).
Then, if none document has been found, none document will be updated.
What happens if we look for a document using shifts._id:2?
This tells mongo "search a document where shifts field has an object with _id equals to 2". This query works ok (example) but be careful, this returns the WHOLE document, not only the array which match the _id.
This not return:
[
{
"_id": 1,
"shifts": [
{
"_id": 2
}
]
}
]
Using this query mongo returns the ENTIRE document where exists a field called shifts that contains an object with an _id with value 2. This also include the whole array.
So, with tat, you know why find object works. Now adding this to an update query you can create the query:
This one to remove all shifts._id which are equal to 2.
db.collection.update({
"shifts._id": 2
},
{
$pull: {
shifts: {
_id: 2
}
}
})
Example
Or this one to remove shifts._id if parent _id is equal to 1
db.collection.update({
"_id": 1
},
{
$pull: {
shifts: {
_id: 2
}
}
})
Example

Ensuring exactly N items with value X remain in an array with mongodb

Assuming we have a document in my MongoDB collection like the following:
{
"_id": "coffee",
"orders": [ "espresso", "cappuccino", "espresso", ... ],
}
How do I use a single update statement that ensures there are exactly say 2 espressos in this document, without knowing how many there are to begin with?
I know that using 2 consecutive statements I can do
db.test.update(
{ _id: "coffee" },
{ "$pull": { "orders": "espresso" } }
);
followed by
db.test.update(
{ "_id": "coffee" },
{ "$push": { "orders": { "$each": ["espresso", "espresso"] } } }
);
But when combining both into a single statement, MongoDB balks with an error 40, claiming Updating the path 'orders' would create a conflict at 'orders' (understandable enough - how does MongoDB what to do first?).
So, how can I do the above in a single statement? Please note that since I'll be using the above in the context of a larger unordered bulk operation, combining the above in an ordered bulk operation won't work.
Thanks for your help!

Mongo aggregate group by multiple values

I have a Mongo query which I want to effectively use the $group in the same way as GROUP BY in SQL.
This isn't working for me unless I set the _id of the new document one of the group categories which doesn't work for me and also, I am not able to get the values I want which come from potentially THREE documents which I am merging together in Mongo.
In SQL, I would write something like to illustrate the grouping and select that I am using as the basis of my aggregation in Mongo:
SELECT entity_id, connection_id, cycle_id, objectOriginAPI,accountBalance
FROM raw_originBusinessData
WHERE objectStatus = 'UPROCESSED'
AND (objectOriginAPI = 'Profit & Loss'
OR objectOriginAPI = 'Balance Sheet'
OR objectOriginAPI = 'Bank Summary')
GROUP BY entity_id, connection_id, cycle_id;
I have paraphrased to simplify what my Mongo script is doing with embedded arrays.
db.getCollection('raw_originBusinessData').aggregate([
{ "$match": {
objectStatus : "UNPROCESSED"
, $or: [
{ objectOriginAPI : "Profit & Loss"}
,{objectOriginAPI : "Balance Sheet"}
,{objectOriginAPI : "Bank Summary"}
]}
},
// don't worry about this, this is all good
{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" },
// this is where I believe I'm having my problem
{ "$group": {"_id": "$entity_id"
// , "$connection_id"
// , "objectCycleID"
, "accountBalances": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
{$project: {objectClass: {$literal: "Source Data"}
, objectCategory: {$literal: "Application"}
, objectType: {$literal: "Account Balances"}
, objectOrigin: {$literal: "Xero"}
, entity_ID: "$_id"
, connection_ID: "$connection_ID"
, accountBalances: "$accountBalances"}
}
]
// ,{$out: "std_sourceBusinessData"}
)
So each of the documents I am combining into a single document have the same entity_id, connection_id and cycle_id which I want to put into the new document. I also want to ensure that the new document has it's own unique object_id.
Your help is very much appreciated - Mongo documentation doesn't cover anything about $group other than _id is mandatory but if I don't set the _id to something that I want to group by (in the above script it is set to entity_id) it doesn't group properly.
Put simply, the _id needs to be a "composite" value, and therefore comprised of three "sub-keys":
{ "$group":{
"_id": {
"entity_id": "$entity_id"
"connection_id": "$connection_id",
"objectCycleID": "$objectCycleID"
},
"accountBalances": {
"$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value"
}
}},
{ "$project": {
"_id": 0,
"objectClass": { "$literal": "Source Data" },
"objectCategory": { "$literal": "Application"},
"objectType": { "$literal": "Account Balances"},
"objectOrigin": { "$literal": "Xero"},
"entity_ID": "$_id.entity_id",
"connection_ID": "$_id.connection_id",
"accountBalances": "$accountBalances"
}}
And then of course, referncing any of those values in the later $project requires you now prefix with $_id as that is now the parent key.
Just as with any MongoDB document, the _id can be anything that is a valid BSON Object in representation. So in this case, the combination means "group on all these field values".

MongoDB query to find property of first element of array

I have the following data in MongoDB (simplified for what is necessary to my question).
{
_id: 0,
actions: [
{
type: "insert",
data: "abc, quite possibly very very large"
}
]
}
{
_id: 1,
actions: [
{
type: "update",
data: "def"
},{
type: "delete",
data: "ghi"
}
]
}
What I would like is to find the first action type for each document, e.g.
{_id:0, first_action_type:"insert"}
{_id:1, first_action_type:"update"}
(It's fine if the data structured differently, but I need those values present, somehow.)
EDIT: I've tried db.collection.find({}, {'actions.action_type':1}), but obviously that returns all elements of the actions array.
NoSQL is quite new to me. Before, I would have stored all this in two tables in a relational database and done something like SELECT id, (SELECT type FROM action WHERE document_id = d.id ORDER BY seq LIMIT 1) action_type FROM document d.
You can use $slice operator in projection. (but for what you do i am not sure that the order of the array remain the same when you update it. Just to keep in mind))
db.collection.find({},{'actions':{$slice:1},'actions.type':1})
You can also use the Aggregation Pipeline introduced in version 2.2:
db.collection.aggregate([
{ $unwind: '$actions' },
{ $group: { _id: "$_id", first_action_type: { $first: "$actions.type" } } }
])
Using the $arrayElemAt operator is actually the most elegant way, although the syntax may be unintuitive:
db.collection.aggregate([
{ $project: {first_action_type: {$arrayElemAt: ["$actions.type", 0]}
])