get array of objects where boolean is true - mongodb

this is my collection
{
"_id": "bRu9ExERzz8PCDwRp",
"persian_title": "عنوان پارسی",
"english_title": "english title",
"price": 5000,
"offer_price": 2000,
"free_for_all": false,
"is_offer": false,
"author_id": "JH3hJGsuYFnRLFLWY"
"Seasons": [
{
"title": "intro",
"free_for_all": false,
"Episodes": [
{
"title": "first episode",
"length": "12",
"url": "0.mp4",
"free_for_all": true
},
{
"title": "second episode",
"length": "05",
"url": "1.mp4",
"free_for_all": false
}
]
}
]
}
i'm trying to get Seasons , episodes where free_for_all is true.
tried this but it doesn't work.
db.courses.find({_id:"bRu9ExERzz8PCDwRp"}, {
"Seasons": {
"$elemMatch": {
"Episodes": {
"$elemMatch": {
"free_for_all": true,
}
}
}
}
})
the result is just like this query :
db.courses.find({_id:"bRu9ExERzz8PCDwRp"})
how can i get only free seasons and episodes?

Your question is ambiguous regarding the desired outcome for free season with non-free episodes, and vice versa, free episodes in non-free seasons. So I'm assuming you want only episodes that are free and are part of a free season. That's what the following will give you (not tested):
_.reduce(db.courses.findOne({_id:"bRu9ExERzz8PCDwRp"}).Seasons, function(all, s) {
if (s.free_for_all) {
all = _.reduce(s.Episodes, function(memo, e) {
if (e.free_for_all) memo.push(e);
return memo;
}, all);
}
return all;
}, []);
If you want all episodes that are free or part of a free season:
_.reduce(db.courses.findOne({_id:"bRu9ExERzz8PCDwRp"}).Seasons, function(all, s) {
if (s.free_for_all) {
all = all.concat(s.Episodes);
} else {
all = _.reduce(s.Episodes, function(memo, e) {
if (e.free_for_all) memo.push(e);
return memo;
}, all);
}
return all;
}, []);

Related

How to update jarray in jsonb field?

I have a jsonb field that contained the something like below:
How to update is_read properties in extras node to true where the users_pid = 1 and is_read=false?
I have tried below:
UPDATE chats
SET attributes = jsonb_set(
cast(attributes->'data'->>'extras' AS jsonb),
array['is_read'],
to_jsonb(true)
)
WHERE users_pid =1
AND cast(attributes->'data'->'extras_to'- >>'is_read' AS boolean) = false
but nothing updated
[
{
"data": {
"users_pid": 1,
"datetime": "2022-05-01 13:10:58",
"extras": {
"is_read": false,
"read_dt": ""
}
}
},
{
"data": {
"users_pid": 3,
"datetime": "2022-05-23 11:03:22",
"extras": {
"is_read": false,
"read_dt": ""
}
}
},
{
"data": {
"users_pid": 1,
"datetime": "2022-05-13 11:23:22",
"extras": {
"is_read": false,
"read_dt": ""
}
}
}
]

How can I paginate using Resource<T> using Page<T>

I am using the following code to create a paginated list of JSON data for Artist objects:
#RequestMapping(value = "/artists/all", method = RequestMethod.GET, produces = {"application/hal+json"})
public Resources<Artist> getArtists(Pageable pageable) {
final Page<Artist> allArtists= artistService.GetAllArtists(pageable);
for (final Artist artist : allArtists) {
Long artistId = artist.getArtistId();
Link selfLink = linkTo(methodOn(ArtistController.class).getAllArtistById(artistId)).withSelfRel();
artist.add(selfLink);
final Link ordersLink = linkTo(methodOn(MusicController.class).getMusicByArtistId(artistId, pageable)).withRel("musics");
artist.add(ordersLink);
}
Link link =linkTo(ArtistController.class).withSelfRel();
Resources<Artist> result = new Resources<>(allArtists,link);
return result;
}
The code currently returns outputs that are in this format:
{
"artistId": 2,
"name": "Simon Mburu",
"_links": {
"self": {
"href": "http://localhost:8000/api/v1/artists/2"
},
"musics": {
"href": "http://localhost:8000/api/v1/musics/artist/2"
}
}
}
However my intent is to have the code return an output like this:
"pageable": {
"sort": {
"sorted": false,
"unsorted": true
},
"offset": 0,
"pageSize": 20,
"pageNumber": 0,
"paged": true,
"unpaged": false
},
"last": true,
"totalPages": 1,
"totalElements": 2,
"size": 20
"number": 0,
"numberOfElements": 2
"sort": {
// ETC...
What changes can I make to my code to get it to output the data contained in the above example instead of what it currently outputs?

group by properties and sum of values between nested json and array of objects

I have users array with their name,
var users = [{'name':'zulekha'}, {'name':'deepika'}];
I am fetching worklogged by each user from jira APIs. So I am getting object like this.
var worklogResult = {
"issues": [
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "zulekha",
},
"timeSpentSeconds": 180
},
{
"author": {
"name": "deepika",
},
"timeSpentSeconds": 210
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "deepika",
},
"timeSpentSeconds": 140
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": [
{
"author": {
"name": "zulekha",
},
"timeSpentSeconds": 600,
}
]
}
}
},
{
"fields": {
"worklog": {
"worklogs": []
}
}
}
]
}
Now I want to match worklogResult with users in such a way that I can get following output.
output = [{'name':'zulekha','timeSpentSeconds':780}, {'name':'deepika', 'timeSpentSeconds':350}]
Can anyone suggest me how to achieve this?
use _.flatMap to flat nested objects
_.chain(worklogResult.issues)
.flatMap('fields.worklog.worklogs')
.thru(function(spents) {
return _.map(users, function(user) {
return _.merge(user, {
timeSpentSeconds: _.chain(spents)
.filter(['author.name', user.name])
.map('timeSpentSeconds')
.sum()
.value()
})
})
})
.value()

swift firebase retrieve all object that the child of the object have the same key

Below is my firebase and code , I would like to retrieve all activities which have the User John key inside User.
let ref = FIRDatabase.database().reference().child("activities/")
ref.queryOrderedByChild("User").queryEqualToValue("John").observeSingleEventOfType(.Value,
withBlock:{
(snapshot) in
for record in snapshot.children
{
}
})
This is not working because in your query you are trying to take all the activities having an attribute User == "John" when the real value of User is an Object like this:
{
"John": {
"age": 21
}
}
To solve this issue you should change your data structure creating a node where you save all your users, and keep in users/userID/activities only the id of the activities. For example, this would be a nicer way to structure your data:
{
"activities": {
"cycling": {
"users": {
"user1": true,
"user2": true
}
},
"running": {
"users": {
"user1": true
}
}
},
"users": {
"user1": {
"name": "John",
"age": 21,
"activities": {
"cycling": true,
"running": true,
}
},
"user2": {
"name": "Tim",
"age": 20,
"activities": {
"cycling": true
}
}
}
}
Then you can use
Let me know if this helped ;)

Finding multiple docs using same id not working, using meteor + react and mongoDB

How do I get the email address of the students in the same class_id, take it as there are more then 2 students in different class in the DB as well?
I have this but it return empty array []
Meteor.users.find({"course_learn_list.$.class_id": {$in: [classId]}},
{field: {"emails.address": 1}}
).fetch()
Collections
{
"_id": "LMZiLKs2MRhZiiwoS",
"course_learn_list": [
{
"course_id": "M8EiKfxAAzy25WmFH",
"class_id": "jePhNgEuXLM3ZCt98"
},
{
"course_id": "5hbwrfbfxAAzy2nrg",
"class_id": "dfbfnEuXLM3fngndn"
}
],
"emails": [
{
"address": "student1#gmail.com",
"verified": false
}
]
},
{
"_id": "JgfdLKs2MRhZJgfNgk",
"course_learn_list": [
{
"course_id": "M8EiKfxAAzy25WmFH",
"class_id": "jePhNgEuXLM3ZCt98"
},
{
"course_id": "5hbwrfbfxAAzy2nrg",
"class_id": "dfbfnEuXLM3fngndn"
}
],
"emails": [
{
"address": "student2#gmail.com",
"verified": false
}
]
}
I think you want:
Meteor.users.find({ "course_learn_list.class_id": classId },
{ "course_learn_list.$": 1, "emails.address": 1 }).fetch()
This should find the first instance in each course_learn_list array where the classId is your classId.
In this case you probably don't need to use a projection to get the right answer. Here's an example of extracting the verified email addresses using only the . operator in the selector:
const ids = ['jePhNgEuXLM3ZCt98', 'some-other-id'];
const emails =
Meteor.users.find({ 'course_learn_list.class_id': { $in: ids } })
.fetch()
.map(user => _.findWhere(user.emails, { verified: true }).address);
This works for me!
Meteor.publish("getMyClassStudents", function(classId) {
console.log("Publish getMyClassStudents")
var self = this
if (self.userId) {
var data = Meteor.users.find({
"course_learn_list.class_id": classId
}, {
"fields": {
"emails.address": 1
}
})
return data
}
else {
return self.ready()
}
})