I have a schema which looks like this:
{
"_id" : ObjectId("4f6af5c7065f92581a000013"),
....
"conversation" : [{
"_id" : ObjectId("4f6af5c7065f92581a000013"),
"msg" : "message1",
"userID" : 1
},{
"_id" : ObjectId("4f6af5c7065f92581a000016"),
"msg" : "message3",
"userID" : 1
},{
"_id" : ObjectId("4f6af5c7065f92581a000023"),
"msg" : "msg",
"userID" : 1
}]
}
What I need is to output a list of elements whose value for the key msg contains 'msg'
Is it possible to do so?
db.dialogs.find({ "_id" : new ObjectId('4f6af5c7065f92581a000013'), "conversation.msg" : /msg/i })
but it outputs all the information about the object. What I need is just
{
"_id" : ObjectId("4f6af5c7065f92581a000023"),
"msg" : "msg",
"userID" : 1
}
No, you can't select elements of sub-array on their own. Structure of parent document will be preserved (though, you may choose not to select from fields other tnan conversation (as you did in the example)).
Related
I'm struggling to insert data inside a nested array in MongoDB.
My schema looks like this:
{
"_id" : ObjectId("5c0c55642440311ff0353846"),
"name" : "Test",
"email" : "test#gmail.com",
"username" : "test",
"password" : "$2a$10$RftzGtgM.DqIiaSvH4LqOO6RnLgQfLY3nk7UIAH4OAvvxo0ZMSaHu",
"created" : ISODate("2018-12-08T23:36:04.464Z"),
"classes" : [
{
"_id" : ObjectId("5c0c556e2440311ff0353847"),
"cName" : "1A",
"student" : [
{
"grades" : [ ],
"_id" : ObjectId("5c0c55812440311ff0353848"),
"name" : "StudentName",
"lname" : "StudenteLastName",
"gender" : "M"
}
insert }
],
"__v" : 0
}.
What I want to do is inserting a grade for the student inside "grades" array.
Expected result is:
{
"_id" : ObjectId("5c0c55642440311ff0353846"),
"name" : "Test",
"email" : "test#gmail.com",
"username" : "test",
"password" : "$2a$10$RftzGtgM.DqIiaSvH4LqOO6RnLgQfLY3nk7UIAH4OAvvxo0ZMSaHu",
"created" : ISODate("2018-12-08T23:36:04.464Z"),
"classes" : [
{
"_id" : ObjectId("5c0c556e2440311ff0353847"),
"cName" : "1A",
"student" : [
{
"grades" : [6],
"_id" : ObjectId("5c0c55812440311ff0353848"),
"name" : "StudentName",
"lname" : "StudenteLastName",
"gender" : "M"
}
]
}
],
"__v" : 0
}.
I tried some queries but none of them helped me, even searching a lot.
db.teachers.update({"_id": ObjectId("5c0c55642440311ff0353846"), "classes._id": ObjectId("5c0c556e2440311ff0353847"), "classes.student._id": ObjectId("5c0c55812440311ff0353848")},{$addToSet: {"classes.$.student.grades":6}})
Basically, I searched for the student with the first curly bracket (if I do "db.teachers.find(the three conditions) the result is correct) and then add to the grades array (of Integer) the value 6. But at this point I get errors, I think I'm making a mistake on the "adding" part.
I need also to do the same thing in Mongoose.
Any help is appreciated, thanks in advance!
Edit: I solved. I post my solution hoping it'll be useful to other:
For pushing inside a triple nested array do:
db.teachers.update({"_id":ObjectId("5c0c59985ae5981c58937e12"),"classes":{ $elemMatch : { _id : ObjectId("5c0c59a35ae5981c58937e13") }},"classes.student": { $elemMatch : { _id : ObjectId("5c0c59aa5ae5981c58937e14")} }},{$addToSet:{"classes.$.student.0.grades":3}})
https://docs.mongodb.com/manual/tutorial/query-array-of-documents/
Try using $elemMatch
"classes":{ $elemMatch : { _id : ObjectId("5c0c556e2440311ff0353847") }},
"classes.student": { $elemMatch : { _id : ObjectId("5c0c55812440311ff0353848")} }
I have a collection with some documents like below:
{
"_id" : ObjectId("1"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:00:00.000+01:00"),
"status" : "A"
}
{
"_id" : ObjectId("2"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:01:00.000+01:00"),
"status" : "B"
}
{
"_id" : ObjectId("3"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:02:00.000+01:00"),
"status" : "C"
}
{
"_id" : ObjectId("4"),
"className" : "model.MyClass",
"createdOn" : ISODate("2018-10-23T11:03:00.000+01:00"),
"status" : "D"
}
Given a specific ID, how can I get the previous document that whose status not equals a specific status.
For example, I give the ID 4 and like to get the last document that status not is B neither C. So, I get the Object with Id 1.
How to create this query?
you could try this:
db.yourcollection.find( {"status":{"$nin":["B","C"]}}
).sort({_id:-1}).limit(1);
so use not in operator i.e. $nin, then sort the data in descending order and limit the records to 1
see below documentations for details.
$nin operator
mongo sort
Assumed i have the following Document structure.
{
"_id" : "ehbpidnopgpgcghgakiiiallielefonk",
"users" : 11.87,
"ratingTopMost" : {
"average" : NumberInt("4"),
"users" : NumberInt("3174"),
},
"reviews" : {
"average" : NumberInt("5"),
"count" : NumberInt("51"),
"comments" : [
{
"_id" : ObjectId("5b87b1a07267ad001da7e733"),
"name" : "Batista1395",
"comment" : "Great Stackoverflow",
"datum" : ISODate("2017-01-16T00:00:00.000+01:00"),
"rating" : NumberInt("3")
},
{
"_id" : ObjectId("5b87b1a07267ad001da7e732"),
"name" : "Tim Ace",
"comment" : "I Like it.",
"datum" : ISODate("2016-08-17T00:00:00.000+02:00"),
"bewertung" : NumberInt("5")
},
]
},
}
I need to query the top most 20 documents with the following criteria:
Top most value for rantingTopMost.average
Top most value for ratingTopMost.users
Top most value for reviews.count
Top most value for reviews.average
Top most value for users
The priority should from top to bottom (1 to 5).
Nice to have too: sort the embedded comments by Date DESC.
I must be overlooking really simple, here's a sample of my db :
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product1", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product2", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product3", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product3", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
I'm trying to get 2 results only using :
db.products.find({timestamp:1415478797263,processed:0},{},{limit:2})
I have read and tried similar questions on Stack Overflow, so please keep that in mind before flagging as duplicate.
No matter what I try it gives me the full set... The strangest thing is that I'm using a similar find() elsewhere and it works. An experienced pair of eyes should be able to spot the problem, thanks in advance!!
use this query, does it work?
db.products.find({timestamp:1415478797263,processed:0}).limit(2)
now to use it with node js native driver you can do this
db.products.find({timestamp:1415478797263,processed:0}).limit(2).each(function(err, doc) {
console.dir(doc);
});
or in array form you can get this as
db.products.find({timestamp:1415478797263,processed:0}).limit(2).toArray(function(err, docs) {
console.log("Returned #" + docs.length + " documents");
})
I'm kind of stuck with the following problem. I have a MongoDB filled with documents, of these documents (I have a list with Id's) I need to insert a field.
I have this document:
{
"id" : 3639,
"type" : "P",
"createdate" : "2011-10-19T11:45:14+0200",
"name_creator" : "",
"latitude" : "50.887",
"longitude" : "9.14999",
"themes" : [{
"name" : "Fun",
"id" : "4"
}, {
"name" : "Kids",
"id" : "5"
}]
}
I need a query the can insert the themes field into the document, the current themes field does not have to be updates, just 1 new one. I have over 300 Id's where this has to be done.
The document should then look like this:
(all the other fields in themes should be removed, just one new one 'Outside')
{
"id" : 3639,
"type" : "P",
"createdate" : "2011-10-19T11:45:14+0200",
"name_creator" : "",
"latitude" : "50.887",
"longitude" : "9.14999",
"themes" : [{
"name" : "Outside",
"id" : "6"
}]
}
I would normally write a bit of Java code that would loop over the documents and change them, but I believe (hope) this could be done in a query.
Anyone got an idea on how I could do this?
Thanks for any help!
All you need to do is
db.collection.update(
{id : {$in : [your list of ids]}},
{$set : {
theme : [{
"name" : "Outside",
"id" : "6"
}]
}},
{multi : true}
)