Basically wanted to push data within array of array i.e publicHolidays is outer array and holidayList is inner array. This is mongodb schema looking right now.
"publicHolidays" : [
{
"location" :"pune"
"year" : 2016
"holidayList"[
{
"holidayDate" :"2016-11-09",
"holidayName":"Diwali"
}
]
}
]
I am expecting below schema,wanted to push data in holidayList.
"publicHolidays" : [
{
"location" :"pune"
"year" : 2016
"holidayList"[
{
"holidayDate" :"2016-11-09",
"holidayName":"Diwali"
}
{
"holidayDate" :"2016-1-09",
"holidayName":"padwa"
}
{
"holidayDate" :"2016-12-10",
"holidayName":"holi"
}
]
}
]
Solved issue:
//Add Holidays in Exist Location
'companySettings.updatePublicHolidays'(formValues){
CompanySettings.update(
{
'_id': formValues.UniqueID,
'publicHolidays' : {$elemMatch : {'location': formValues.holidaysLocation,'year': formValues.holidayYear} }
},
{
$push : {'publicHolidays.$.holidayList':
{
'holidayDate' : formValues.leaveDate ,
'holidayName' : formValues.holidayName
}
}
}
);
},
Related
I have a database of products in MongoDB. Inside main objects, there is another object "GL_related", and inside the "GL_related" object there is an array "also_viewed". How can I count the elements inside the "also_viewed" array of a specific object with the title "Sunglasses"(by using the aggregate pipeline method)?
The result should be "4".
Sample data:
/* 1 */
{
"_id" : ObjectId("5d0b6d1cd7367de7f58b4908"),
"GL_asin" : "0456840532",
"GL_title" : "Sunglasses",
"GL_related" : {
"also_viewed" : [
"B001K9DPPC",
"B00BV9MU2K",
"B0042FHTDK",
"B003KK5LEW"
]
}
}
/* 2 */
{
"_id" : ObjectId("5d0b6d1cd7367de7f58b4907"),
"GL_asin" : "0456856293",
"GL_title" : "T-Shirt",
"GL_related" : {
"also_viewed" : [
"B005P1HF2U",
"B006K5JWOE"
]
}
}
You can just use Mongo's dot notation combined with $size
db.collection.aggregate([
{
"$project": {
itemCount: {
$size: "$GL_related.also_viewed"
}
}
}
])
Mongo Playground
I'm trying to do something which should be pretty straightforward. The aggregrate pipeline allows you to pass documents through stages in sequence. For example, I can filter out some documents and pass the documents I want to the next stage. This can be accomplished with $match. Then I want to take the remaining documents and group them by a field to check for duplicates. But I am having major issues with this. This is what I have tried:
db.my_fields.aggregate(
{ '$match' : { related_code_id: { "$in" : [ BSON::ObjectId('5cddd0143ed1495e5c000008'),BSON::ObjectId('5cddd0143ed1495e5c000010')] } } },
{ '$group' : { _id: { 'field' : '$field', 'field_type_id' : '$field_type_id' }, count: { '$sum' : 1} } },
{'$match' : { count: {'$gt' : 1} } }
)
The query works fine except for the first $match. Inside the $in statement, I am getting this error:
2019-05-17T18:47:56.602-0400 E QUERY [js] SyntaxError: missing ] after element list #(shell):2:95
It is complaining about this part right here:
BSON::ObjectId('5cddd0143ed1495e5c000008'),BSON::ObjectId('5cddd0143ed1495e5c000010')
How can I resolve this issue and achieve my goal of getting this basic query working?
Converting the ObjectId to BSON isn't needed:
https://docs.mongodb.com/manual/reference/method/db.collection.find/#query-using-operators
// ...
'$match': {
related_code_id: {
"$in": [
ObjectId('5cddd0143ed1495e5c000008'),
ObjectId('5cddd0143ed1495e5c000010')
]
}
}
// ...
If you are using Mongoose as ORM, you can solve it as follows.
db.my_fields.aggregate(
{ '$match' : { related_code_id: { "$in" : [ mongoose.Types.ObjectId('5cddd0143ed1495e5c000008'),mongoose.Types.ObjectId('5cddd0143ed14 95e5c000010')] } } },
{ '$group' : { _id: { 'field' : '$field', 'field_type_id' : '$field_type_id' }, count:
{ '$sum' : 1} } },
{'$match' : { count: {'$gt' : 1} } }
)
I have simple mapping - one string field and one string[] field.
The array of strings contains duplicate values, and I get those duplicate values in query:
{ "query" : { "term" : {"id" : "579a252585b8c5c428fa0a3c"} } }
Returns a single valid hit:
{
"id" : "579a252585b8c5c428fa0a3c",
"touches" : [ "5639abfb5cba47087e8b4571", "5639abfb5cba47087e8b4571", "5639abfb5cba47087e8b4571", "5639abfb5cba47087e8b457b", "5639abfb5cba47087e8b457b"
}
But in metric script aggregation:
"aggs": {
"path": {
"scripted_metric": {
"map_script": "_agg['result'] = doc['touches'].values"
}
}
}
retuns
"aggregations" : {
"path" : {
"value" : [ { }, {
"result" : [ "5639abfb5cba47087e8b4571", "5639abfb5cba47087e8b457b" ]
}, { }, { }, { } ]
}
}
that element is org.elasticsearch.index.fielddata.ScriptDocValues$Strings, casting it toString() returns a json-encoded 2-element array.
So, the question:
Why does ScriptDocValues$Strings return only unique array values and how to get the initial array in script aggregation?
Thanks.
UPD
I found that for numerical values (in particular floats) everything works perfect.
I have the following document:
{
"_id":"575322d9585095d9929554ba",
"Level1":{
"Level2":[
{
"Level3a":{
"Level4":{
"Level5":{
"name":"John",
"surname":"Matthew"
}
}
}
},
{
"Level3a":{
"Level4":{
"Level5":{
"name":"Emma",
"surname":"Jackson"
}
}
}
}
]
}
}
I need to insert the new name and surname at Level5. I tried the $push method but I got the error that the dotted field .. is not valid for storage:
db.names.update({ "_id":"575322d9585095d9929554ba" },
{
$push: {
"Level1.Level2":
{ $each: [ { "Level3a.Level4.Level5.name": "Greg" },
{ "Level3a.Level4.Level5.surname": "Cook" }] } } } )
It seems that push does not allow the inserting new data in hierarchical arrays or I am wrong?
There is an issue with your query as $each is used to add multiple values to same array....
As we are going to add only one entry to array we don't need to use $each
so query looks like this:
db.vnenad.update({
"_id" : "575322d9585095d9929554ba"
},
{
$push : {
"Level1.Level2" : {
"Level3a" : {
"Level4" : {
"Level5" : {
"name" : "johnny",
"surname" : "rambo"
}
}
}
}
}
})
as I was debbuging your query I decided to create variable with document to insert inside an array, then it was easier for me to adjust your query - please see below:
var doc = {
"Level3a" : {
"Level4" : {
"Level5" : {
"name" : "johnny",
"surname" : "rambo"
}
}
}
}
db.vnenad.update({
"_id" : "575322d9585095d9929554ba"
},
{
$push : {
"Level1.Level2" : doc
}
})
my schema looks like this:
var exampleSchema = newSchema({
profile:{
experience :[{
exp : String
}]
}
});
this is the codes to update experience in profile collection:
exampleSchema.statics.experience = function (id,experience, callback){
var update = {
$push: {
'profile.experience': experience
}
}
this.findByIdAndUpdate(id,update,function(err) {
if (err) {
callback(err);
} else {
callback(null);
}
})
I was getting error like The field 'profile.experience' must be an array but is of type String in document {_id: ObjectId('5653f1d852cf7b4c0bfeb54a')}[object Object]
console.log(experience) is equal to
{ exp: 'jlkjlkjlk' }
my collection should look like this:
experience:[
{
exp : "YYYY"
},
{
exp:"xxxx"}
]
Imagine that you have this collection:
/* 1 */
{
"_id" : ObjectId("565425e862760dfe14339ba8"),
"profile" : {
"experience" : [
{
"exp" : "Experto"
}
]
}
}
/* 2 */
{
"_id" : ObjectId("565425f562760dfe14339ba9"),
"profile" : {
"experience" : {
"exp" : "Experto"
}
}
}
/* 3 */
{
"_id" : ObjectId("5654260662760dfe14339baa"),
"profile" : {
"experience" : "Experto"
}
}
If you try (update doc /* 2 */):
db.profile.update(
{ _id: ObjectId("565425f562760dfe14339ba9") },
{ $push: { "profile.experience" : { exp : "Intermediate" } } }
)
You get this error:
The field 'profile.experience' must be an array but is of type Object
in document {_id: ObjectId('565425f562760dfe14339ba9')}
And if you try (update doc /* 3 */):
db.profile.update(
{ _id: ObjectId("5654260662760dfe14339baa") },
{ $push: { "profile.experience" : { exp : "Intermediate" } } }
)
You will get:
The field 'profile.experience' must be an array but is of type String
in document {_id: ObjectId('5654260662760dfe14339baa')}
i changed Schema like this
experience : [{type:String,exp:String}],
my update object looks like this
var update = {
$push: {
'profile.experience': san.exp
}
};
san looks like this :{ exp: 'YYY' }
Inside mongoose collectionlooks like this used RoboMongo
"experience" : [
"experienced in XXX",
"YYY"
],
$push: {
'profile.experience': experience
}
Remove .exp.
First you have to check you declared your field as an array like this(look at field products):
shop = {
'name': "Apple Store",
'description': "",
'direction': "",
'contact': "",
'products':[]
}
Now if you want to add something to the field products using $push
product = {
'name': "Iphone 6",
'description': "Iphone model 6, 64GB",
'price': 700,
'count': 3
}
myquery = { "name" : "Apple Store" }
obj ={"$push":{"products":{"$each": [product]}}}
db.collection.update_one(myquery,obj)
This code is provided for PyMongo framework. To use in MongoDB directly replace update_one by update. Mongo resource
You may use $set instead of $push which might work.
$set: {
'profile.experience': experience
}
are you searching for adding multiple values into single field then use this one.
write this one your model or schema:
arrayremarks:[{remark: String}]
then write in your controller:
module.exports.addingremarks = (req, res) => {
let casenum=JSON.parse(JSON.stringify(req.body.casenum).replace(/"\s+|\s+"/g,'"'))
var rem={remark:"Suman macha"}
Inwart.update( { 'casenum': casenum },{ $push: { arrayremarks:rem} } ,function (err, inwarts) {
if (err)
return console.error(err);
res.send(inwarts);
}
)
}