I got multiple documents like this:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM",
"timestamp" : 1453731403807,
"message" : "some text",
"name" : "Tom"
},
{
"id" : "BAHx9KeKjuMePce6f",
"timestamp" : 1453731403808,
"message" : "some text",
"name" : "Bob"
},
{
"id" : "ePce6fBAHx9KeKjuM",
"timestamp" : 1453731403809,
"message" : "some text",
"name" : "Tom"
}
]
}
I get this document by using this find-query:
Collection.find({}, { sort: { title: 1 }});
But I don't need the complete notes field. I'm only interested in the id of the last note-object. That means I have to order all notes object by timestamp and just take the first (=newest) one.
I'm not quite sure, if I can do that by the find-query or if I have to do that after getting the complete data.
So the best result for me would be:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM"
}
]
}
You can use the $slice projection to limit the number of array elements returned. For example:
db.collection.find({}, {title: 1, "notes.id": 1, notes: {$slice: 1}}).sort({title: 1});
Will return:
{
"_id" : "sgG6G9XTvvjj7uxwQ",
"title" : "A title",
"notes" : [
{
"id" : "ePce6fBAHx9KeKjuM"
}
]
}
Related
I am using mongoDB as backend server, I have nested array(one level array) like this
{
"_id" : ObjectId("60b1fc6d3c43f74e0c1dba92"),
"seriesId" : "60acebf73acb5b3a98d14331",
"name" : "Season 1",
"logoURL" : "uploads/season/1622277216401.png",
"yearOfPublish" : "2021-05-29",
"description" : "Season 1",
"createdBy" : ObjectId("609cbf49ba46cc3924859ab5"),
"createdOn" : "2021-05-29T08:33:49.480Z",
"episode" : [
{
"seasonId" : "60b1fc6d3c43f74e0c1dba92",
"name" : "Episode 1",
"id" : 0,
"logoURL" : "uploads/episode/1622278616899.png",
"dateOfTelecast" : null,
"description" : "sadfgh",
"duration" : "30",
"videoType" : "customURL",
"embedCode" : "",
"url" : "https://youtu.be/kbpsXMUr7ss",
"liveboxChannel" : "",
"createdOn" : "2021-05-29T08:56:59.230Z",
"createdBy" : ObjectId("609cbf49ba46cc3924859ab5"),
"_id" : "ZaVrpOLO5"
},
{
"seasonId" : "60b1fc6d3c43f74e0c1dba92",
"name" : "Episode 2",
"id" : 0,
"logoURL" : "uploads/episode/1622279206607.png",
"dateOfTelecast" : null,
"description" : "adfd",
"duration" : "30",
"videoType" : "customURL",
"embedCode" : "",
"url" : "https://youtu.be/kbpsXMUr7ss",
"liveboxChannel" : "",
"createdOn" : "2021-05-29T09:06:48.637Z",
"createdBy" : ObjectId("609cbf49ba46cc3924859ab5"),
"_id" : "9GKqXhxcH"
},}
I have more no of seasons. from the season collection,i have episode array under the name of Episode.
Now My frontend page required that episode array alone.
response = {episode: all the episode data} and this episode data is based on skip and limit value
I have tried something in mongodb,
db.getCollection('season_copy').aggregate([
{$project: {
episodes: {
$cond:{ if: { $isArray: "$episode" }, then: { input:"$episode" }, else: 0 }
},
},
},
])
Can anyone suggest me some idea?
Check this out:
Without aggregate:
db.getCollection('season_copy')
.find({ _id: ObjectID(id)})
.project({ episode: 1 }).toArray();
With aggregate:
MongoDB playground
db.getCollection('season_copy')
.aggregate([
{
$match: {
_id: ObjectId("60b1fc6d3c43f74e0c1dba92")
}
},
{
$project: {
episode: 1
}
}
])
I need to find a room by id and update received field to true where user id equals to xx.
The document is here:
{
"_id" : ObjectId("5e5d0d870fc69641a41a3c65"),
"users" : [
ObjectId("5e57d64d92cc878760086980"),
ObjectId("5e57d64592cc87876008697e")
],
"messages" : [
{
"_id" : ObjectId("5e67834b6c8b2d356a4ad9fd"),
"text" : "Hello",
"user" : ObjectId("5e57d64d92cc878760086980"),
"createdAt" : ISODate("2020-03-10T12:08:43.006Z"),
"sent" : true,
"received" : false
},
{
"_id" : ObjectId("5e6783076c8b2d356a4ad9fc"),
"text" : "Hello",
"user" : ObjectId("5e57d64d92cc878760086980"),
"createdAt" : ISODate("2020-03-10T12:07:35.544Z"),
"sent" : true,
"received" : true
}
],
"createdAt" : ISODate("2020-03-02T13:43:35.522Z"),
"updatedAt" : ISODate("2020-03-10T12:08:43.006Z"),
"unReads" : {
"5e57d64d92cc878760086980" : 1,
"5e57d64592cc87876008697e" : 5
},
"__v" : 0
}
****It looks like your post is mostly code; please add some more details.****
You need the positional $ operator:
Model.update({_id: ObjectId("5e5d0d870fc69641a41a3c65"), "messages.user": ObjectId("5e57d64d92cc878760086980")}, { $set: { "messages.$.received": true } })
Wanted to get the clicked tree object value in javascript
what i'm trying to achieve is when user clicks a tree node then its related data i want to get the original object
here is what i have tried not getting object:
$('#jstree').jstree({
"json_data" : {
"data" : [
{
"data" : "A node",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
},
{
"attr" : { "id" : "li.node.id1" },
"data" : {
"title" : "Long format demo",
"attr" : { "href" : "#" }
}
}
]
},
"plugins" : [ "themes", "json_data", "ui" ]
});
$("#jstree").bind(
"select_node.jstree", function(evt, data){
//selected node object: data.node;
console.log('data',data.inst.get_json());
console.log('data.node.id',data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://old.static.jstree.com/v.1.0pre/jquery.jstree.js"></script>
<div id="jstree">
</div>
Expected Output:
from above snippet, when i click Child 1 or A Child 2 i should get below object
{
"data" : "A node",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
}
when user clicks on Long format demo i should get below object
{
"attr" : { "id" : "li.node.id1" },
"data" : {
"title" : "Long format demo",
"attr" : { "href" : "#" }
}
}
Please help me thanks in advance!!!
As your jstree version is old, I recommend you to update your jstree version. but, as for the 1.0v, You can use below code to get the parent node, if user clicked child one.
$('#jstree').jstree({
"json_data" : {
"data" : [
{
"data" : "A node",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
},
{
"attr" : { "id" : "li.node.id1" },
"data" : {
"title" : "Long format demo",
"attr" : { "href" : "#" }
}
}
]
},
"plugins" : [ "themes", "json_data", "ui" ]
});
$("#jstree").bind(
"select_node.jstree", function(evt, data){
if(data.inst._get_parent().length <= 0 || data.inst._get_parent()===-1){
console.log('data',data.inst.get_json());
console.log('data.node.id',data);
}else{
var parent = data.inst._get_parent();
console.log(data.inst.get_json(parent));
}
//selected node object: data.node;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://old.static.jstree.com/v.1.0pre/jquery.jstree.js"></script>
<div id="jstree">
</div>
I have a simple document, which has 3 location objects in an array.
Data:
{
"_id" : ObjectId("57c3c479a306b3613cf1ee5b"),
"location_history" : [
{
"location_name" : "Area 1",
"date" : 1472447609,
"_id" : ObjectId("57c3c479ac5a69612f0e0899"),
"location" : [
24.9532107, 67.1790576
]
},
{
"location_name" : "Area 2",
"date" : 1472448059,
"_id" : ObjectId("57c3c63bac5a69612f0e089c"),
"location" : [
24.9663937, 67.1462044
]
},
{
"location_name" : "Area 3",
"date" : 1472448987,
"_id" : ObjectId("57c3c9dbac5a69612f0e08a0"),
"location" : [
-24.987325, 115.1862298
]
}
}
Question: I need to fetch closest locations in this array.
Query I have tried:
db.getCollection('consumers_locations').aggregate([
{"$unwind": "$location_history"},
{"$match":{"_id":ObjectId("57c3c479a306b3613cf1ee5b")}},
{"$project" : { "abc" : "$location_history.location"} },
{ $geoNear: {
near: { type: "Point", coordinates: [ 24.942785, 67.157855 ] },
distanceField: "distance",
query : {"_id" : "_id"},
uniqueDocs: true,
includeLocs: "search_history.location",
maxDistance : 10000
}
}
])
But I get an error:
"ok" : 0,
"errmsg" : "$geoNear is only valid as the first stage in a pipeline.",
"code" : 2,
"codeName" : "BadValue"
Expected Output:
{
"_id" : ObjectId("57c3c479a306b3613cf1ee5b"),
"location_history" : [
{
"location_name" : "Area 1",
"date" : 1472447609,
"_id" : ObjectId("57c3c479ac5a69612f0e0899"),
"location" : [
24.9532107, 67.1790576
]
},
{
"location_name" : "Area 2",
"date" : 1472448059,
"_id" : ObjectId("57c3c63bac5a69612f0e089c"),
"location" : [
24.9663937, 67.1462044
]
}
}
It is not doable with your schema. Indexes are used to order documents in a collection, not sorting subdocuments within a document.
Consider to create a separate location_history collection with references to the parent document in consumers_locations. E.g. for your object, the collection may look like:
db.getCollection('location_history').insert([
{
"consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
"location_name" : "Area 1",
"date" : 1472447609,
"_id" : ObjectId("57c3c479ac5a69612f0e0899"),
"location" : [
24.9532107, 67.1790576
]
},
{
"consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
"location_name" : "Area 2",
"date" : 1472448059,
"_id" : ObjectId("57c3c63bac5a69612f0e089c"),
"location" : [
24.9663937, 67.1462044
]
},
{
"consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
"location_name" : "Area 3",
"date" : 1472448987,
"_id" : ObjectId("57c3c9dbac5a69612f0e08a0"),
"location" : [
-24.987325, 115.1862298
]
}
]);
Regarding to the error, the docs read:
You can only use $geoNear as the first stage of a pipeline.
since only the first stage can benefit from indexes.
I have a collection of the structure as follows:
collection name : "positions"
Structure
{
"_id" : "vtQ3tFXg8THF3TNBc",
"candidatesActions" : {
"sourced" : [ ],
},
"appFormObject" : {
"name" : "✶ mandatory",
"questions" : [
{
"qusId" : "qs-585494",
"type" : "simple",
"qus" : "Which was your previous company"
},
{
"qusId" : "qs-867766",
"type" : "yesNo",
"qus" : "Are you willing to relocate?",
"disqualify" : "true"
}
]
}
}
I want to update "qus" field of the above collection whose _id is "vtQ3tFXg8THF3TNBc" and "qusId" is "qs-585494".
Try following....
db.positions.update(
{_id: "vtQ3tFXg8THF3TNBc", "appFormObject.questions.qusId":"qs-585494"},
{$set:{"appFormObject.questions.$.qus": "this is updated value"}}
)
Use following query
db.positions.findAndModify({
query: { _id: "vtQ3tFXg8THF3TNBc", "appFormObject.questions.qusId":"qs-585494"} ,
update: { $set: { 'appFormObject.questions.$.qus': 'Brilliant Green' } },
});
Thanks