How create a MongoDB query - mongodb

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

Related

How to get Documents filtered by the top-most and sort embedded result

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.

MongoDb $match for embedded document

db.entities.aggregate([$match : {"Company.Id" : {$gt : 11}}])
above code works in mongo shell but below does not work why ??
db.entities.aggregate([{$match : {Company : {Id : {$gt : 11}}}}])
it displays nothing.
Here is my mongodocument
"_id" : ObjectId("552ca154993cfc98fef1e13c"),
"Name" : "R",
"Address" : "RAdd",
"Company" : {
"Name" : "something",
"Id" : 14
}
From mongodb docs
When the field holds an embedded document, a query can either specify an exact match on the embedded document or specify a match by individual fields in the embedded document using the dot notation.
So this will work
db.entities.aggregate([{
'$match':{
"Company" : {
"Name" : "something",
"Id" : 14
}
}
}
])

MongoDB query insert field into document from a list of Id's

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

mongodb $maxScan didn't equals limit

This is my first question on stack overflow, I am so happy and await your answers. My question is:
When I use MongoDB Query Selectors, I want limit results. But $maxScan is not work as I want.
---------This is What I want result.
db.post.find({query:{status:"publish"},$orderby:{date:-1}},{status:1,name:1,date:1,$slice:2}).limit(3)
{ "_id" : ObjectId("519262580cf21fb1647fb765"), "date" : ISODate("2013-05-14T16:12:08.600Z"), "status" : "publish", "name" : "关于多说" }
{ "_id" : ObjectId("519254ad0cf2f064f6ecef82"), "date" : ISODate("2013-05-14T15:13:49.017Z"), "status" : "publish", "name" : "回顾<蜗居>的100句经典台词" }
{ "_id" : ObjectId("519254690cf2f064f6ecef81"), "date" : ISODate("2013-05-14T15:12:41.462Z"), "status" : "publish", "name" : "女人脱光了是什么" }
-----------This is the results I use $maxScan
db.post.find({query:{status:"publish"},$maxScan:3,$orderby:{date:-1}},{status:1,name:1,date:1})
{ "_id" : ObjectId("518e6c690cf21a363df2956e"), "date" : ISODate("2013-05-11T16:06:01.341Z"), "status" : "publish", "name" : "淘宝新店,充值任务" }
I find may be the $maxScan didn't like limit(). it first limit the collection data and then execute the query! but this is not I want. Is anything i wrong? please help.Thanks
--------------All results
db.post.find({query:{},$orderby:{date:-1}},{status:1,name:1,date:1})
{ "_id" : ObjectId("519262580cf21fb1647fb765"), "date" : ISODate("2013-05-14T16:12:08.600Z"), "status" : "publish", "name" : "关于多说" }
{ "_id" : ObjectId("519254ad0cf2f064f6ecef82"), "date" : ISODate("2013-05-14T15:13:49.017Z"), "status" : "publish", "name" : "回顾<蜗居>的100句经典台词" }
{ "_id" : ObjectId("519254690cf2f064f6ecef81"), "date" : ISODate("2013-05-14T15:12:41.462Z"), "status" : "publish", "name" : "女人脱光了是什么" }
{ "_id" : ObjectId("518ee61a0cf22bd326d60215"), "date" : ISODate("2013-05-12T00:45:14.295Z"), "status" : "publish", "name" : "JSTL日期格式化用法(转载)" }
{ "_id" : ObjectId("518e6c690cf21a363df2956e"), "date" : ISODate("2013-05-11T16:06:01.341Z"), "status" : "publish", "name" : "淘宝新店,充值任务" }
{ "_id" : ObjectId("518e21c90cf21a363df2956d"), "date" : ISODate("2013-05-11T10:47:37.803Z"), "status" : "draft", "name" : "一夜没睡" }
{ "_id" : ObjectId("518df75d0cf21a363df2956c"), "date" : ISODate("2013-05-11T07:46:37.726Z"), "status" : "draft", "name" : "飞娥入侵" }
{ "_id" : ObjectId("518d80630cf21a363df2956b"), "date" : ISODate("2013-05-10T23:18:59.323Z"), "status" : "publish", "name" : "Java的日期格式化常用方法" }
To return only the top results, you should use limit(), which will limit the amount of results returned from the cursor. This is commonly used with skip() to paginate the results.
It's not explained very clearly in the docs, but $maxScan as the name suggests limits the number of documents the query will examine. Presumably your query is examining some documents which don't meet the criteria (with status != publish) and then discarding them.
Do you have an index on status? It's possible that could help the query return the results you want while scanning fewer documents, but I still think limit() is what you want.

mongodb part of the array

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)).