AngularJS get length by filtering 3rd level property - angularjs

I have been trying to get the count of items that have a specific text match for a specific field but I haven't had any luck.
The link below is the closest example I have been able to implement, but all I can get it to return is the total number of entries in the table.
Angular Count Filtered Data
When I insert {{data.length}} into the view, it returns the total number of entries.
But when I change it to query the sub-field as {{(data|filter:{team:'A'}).length}} or {{(data|filter:{custom_fields.team:'A'}).length}} it returns a 0.
[{
"id": 1,
"custom_fields": {
"team": ["A"]
}
},{
"id": 2,
"custom_fields": {
"team": ["B"]
},
},{
"id": 3,
"custom_fields": {
"team": ["A"]
}
}]
Any thoughts or suggestions?

You can do that by filtering nested objects:
{{(data|filter:{custom_fields: {team: ['A']} }).length}}
Demo.

Related

Update field with value from a nested field

I know I can use the pipeline aggregator within update to update the field of one value with the value from another field. However, my issue is when updated a field value based on the value of a nested field. The result of the update always issues the new field with brackets. I don't want brackets/array, I just want it to be a value. See code below
https://mongoplayground.net/p/7ZDP8CYtKK3
db={
"players": [
{
"_id": ObjectId("5fba17c1c4566e57fafdcd7e"),
"username": "moshe",
"health": 0,
"maxHealth": 200,
"Chapters": [
{"Cat A": 25,
"Cat B": 100,
"Cat C": 125}]
}
]
}
Here's the query I apply below
db.players.update(
{username: "moshe"},
[{"$set": {"health": "$Chapters.Cat A"}}]
)
The result yields
[{"Chapters": [
{"Cat A": 25,
"Cat B": 100,
"Cat C": 125}],
"_id": ObjectId("5fba17c1c4566e57fafdcd7e"),
"health": [25],
"maxHealth": 200,
"username": "moshe"
}]
What I want is for the update to health to appear without array brackets as so.... "health":25
Again this is an example based on a much much larger DB I'm working with.
You can use $arrayElemAt or $first(v4.4) operators to select the first element from an array,
db.players.update(
{ username: "moshe" },
[{
"$set": {
"health": {
"$arrayElemAt": ["$Chapters.Cat A", 0]
}
}
}]
)
Playground

MongoDB Array Query - Single out an array element

I am having trouble with querying a MongoDB collection with an array inside.
Here is the structure of my collection that I am querying. This is one record:
{
"_id": "abc123def4567890",
"profile_id": "abc123def4567890",
"image_count": 2,
"images": [
{
"image_id": "ABC123456789",
"image_url": "images/something.jpg",
"geo_loc": "-0.1234,11.234567890",
"title": "A Title",
"shot_time": "01:23:33",
"shot_date": "11/22/2222",
"shot_type": "scenery",
"conditions": "cloudy",
"iso": 16,
"f": 2.4,
"ss": "1/545",
"focal": 6.0,
"equipment": "",
"instructions": "",
"upload_date": 1234567890,
"update_date": 1234567890
},
{
"image_id": "ABC123456789",
"image_url": "images/something.jpg",
"geo_loc": "-0.1234,11.234567890",
"title": "A Title",
"shot_time": "01:23:33",
"shot_date": "11/22/2222",
"shot_type": "portrait",
"conditions": "cloudy",
"iso": "16",
"f": "2.4",
"ss": "1/545",
"focal": "6.0",
"equipment": "",
"instructions": "",
"upload_date": 1234567890,
"update_date": 1234567890
}
]
}
Forgive the formatting, I didn't know how else to show this.
As you can see, it's a profile with a series of images within an array called 'images' and there are 2 images. Each of the 'images' array items contain an object of attributes for the image (url, title, type, etc).
All I want to do is to return the object element whose attributes match certain criteria:
Select object from images which has shot_type = "scenery"
I tried to make it as simple as possible so i started with:
find( { "images.shot_type": "scenery" } )
This returns the entire record and both the images within. So I tried projection but I could not isolate the single object within the array (in this case object at position 0) and return it.
I think the answer lies with projection but I am unsure.
I have gone through the MongoDB documents for hours now and can't find inspiration. I have read about $elemMatch, $, and the other array operators, nothing seems to allow you to single out an array item based on data within. I have been through this page too https://docs.mongodb.com/manual/tutorial/query-arrays/ Still can't work it out.
Can anyone provide help?
Have I made an error by using '$push' to populate my images field (making it an array) instead of using '$set' which would have made it into an embedded document? Would this have made a difference?
Using aggregation:
db.collection.aggregate({
$project: {
_id: 0,
"result": {
$filter: {
input: "$images",
as: "img",
cond: {
$eq: [
"$$img.shot_type",
"scenery"
]
}
}
}
}
})
Playground
You can use $elemMatch in this way (simplified query):
db.collection.find({
"profile_id": "1",
},
{
"images": {
"$elemMatch": {
"shot_type": 1
}
}
})
You can use two objects into find query. The first will filter all document and will only get those whose profile_id is 1. You can omit this stage and use only { } if you wnat to search into the entire collection.
Then, the other object uses $elemMatch to get only the element whose shot_type is 1.
Check an example here

mongoDb embedded query to find list of data

I have the following embedded data And I am trying to get all the transactions which have a same week number for a particular saved account based on the accountId. I tried the following query but it returns an empty array.
savingsAccount.find({accountId: "123456789012345678", transactions: {weekNumber: 32}})
Any Ideas? Thanks so much in advance.
"savingsAccount":
{
"_id": "598cb8686739d49a6f59dbb4",
"accountId": "123456789012345678",
"__v": 2,
"transactions": [
{
"_id": "598cb8a86739d49a6f59dbb5",
"amount": 1234,
"weekNumber": 32,
"date": "2017-08-10T19:48:56.347Z"
},
{
"_id": "598cbb70a4a8f89c18309d87",
"amount": 1234,
"weekNumber": 32,
"date": "2017-08-10T20:00:48.241Z"
}
]
}
This ...
savingsAccount.find({
accountId: "123456789012345678",
'transactions.weekNumber': 32
})
... will return all documents for which accountId is "123456789012345678" and the weekNumber attribute of at least one subdocument in the transactions array is 32.
Your original query returned no matches because the second predicate (transactions: {weekNumber: 32}) was attempting to match elements of the transactions array with the value: {weekNumber: 32} and, since that only represents part of a transactions document, no match was found.
Edit 1: if you want to go further than this to only return the subdocuments in the transactions array which have weekNumber=32 then you have to project and filter (available in versions >= 3.2). Here's an example:
db.savingsAccount.aggregate([
{$match: { accountId: "123456789012345678" }},
{$project: {
accountId: 1,
__v: 1,
transactions: {$filter: {
input: '$transactions',
as: 't',
cond: {$eq: ['$$t.weekNumber', 32]}
}}
}}
])
This will return all documents for which accountId is "123456789012345678" and the weekNumber attribute of at least one subdocument in the transactions array is 32 and for each matched document it will filter the transactions array such that only those subdocuments having weekNumber=32 are returned.

Find all documents but only include a single subdocument if condition applies

I want to return all documents in a collection. But I only want a subdocument to appear in votes array if the userId matches. If it doesn't match I still want the parent document to be returned but without anything appearing in the votes array.
Actual document:
[{ "_id": "...",
"user": {...},
"title": "test",
"votes": [
{"user": "56c265fda0a4335c01205551", "vote": 1},
{"user": "56c265fda0a4335c01205552", "vote": 1},
{"user": "56c265fda0a4335c01205553", "vote": 1},
{"user": "56c265fda0a4335c01205554", "vote": 1}
]}]
What I want if the filter is ...5551: (It IS in the array)
[{ "_id": "...",
"user": {...},
"title": "test",
"votes": [
{"user": "56c265fda0a4335c01205551", "vote": 1}
]}]
What I want if the filter is ...0000: (It isn't in the array)
[{ "_id": "...",
"user": {...},
"title": "test",
"votes": [] //Empty array, but document is still returned.
}]
I found a lot of resources to only include documents if the search value appears in the array, and I can get that value to be the only one that appears, but all of these don't return documents if that value isn't found in the array at all.
How do I get all parent documents to be returned and then filter the votes array so only a single matching element is returned if it is there?
Note: My question is very similar to Retrieve only the queried element in an object array in MongoDB collection but is specific to implementing in Mongoose, not MongoDB.

Multiple search filtering is not working in cloudant, why?

Here i quoted my code for multiple search filtering. I could not find the mistakes in that. please give a right code to make it work well.
Employee document:
{
"_id": "527c8d9327c6f27f17df0d2e17000530",
"_rev": "24-276a8dc913559901897fd601d2f9654f",
"proj_role": "TeamMember",
"work_total_experience": "3",
"personal": {
"languages_known": [
"English","Telugu"
]},
"skills": [
{
"skill_set": "Webservices Framework",
"skill_exp": 1,
"skill_certified": "yes",
"skill_rating": 3,
},
{
"skill_set": "Microsoft",
"skill_exp": 1,
"skill_certified": "yes",
"skill_rating": 3,
}
]
"framework_competency": "Nasscom",
"type": "employee-docs"
}
Design Document:
{
"_id": "_design/sample",
"_rev": "86-1250f792e6e84f6f33447a00cf64d61d",
"views": {},
"language": "javascript",
"indexes": {
"search": {
"index": "function(doc){\n index(\"default\", doc._id);if(doc.type=='employee-docs'){\nif (doc.proj_role){index(\"project_role\", doc.proj_role);}if(doc.work_total_experience){\nindex(\"work_experience\", doc.work_total_experience);}\nif(doc.personal.languages_known){for(c in doc.personal.languages_known){ \n index(\"languages_known\",doc.personal.languages_known[c]);}} if(doc.skills){for (var i=0;i<doc.skills.length;i++){\nindex('skill_set',doc.skills[i].skill_set);}}}}"
}
}
}
Run using below URL : https://ideyeah4.cloudant.com/opteamize_new/_design/sample/_search/search?q=project_role:TeamMember%20AND%20work_experience:%223%22%20AND%20languages_known:Telugu%20AND%20skill_set:Microsoft&include_docs=true
A simple way to debug this is to query the top 100 results in your index:
https://ideyeah4.cloudant.com/opteamize_new/_design/sample/_search/search?q=*:*&limit=100
This will at least tell you whether there are any documents in your index at all.
Your current query (without URL encoding) looks like:
project_role:TeamMember AND work_experience:"3" AND languages_known:Telugu AND skill_set:Microsoft
I'd suggest that some of these search values require quotes - always true when you are searching string values. Next, you could try:
project_role:"TeamMember"
see if you get any results and refine from there.
Debugging this might also be easier if you store the values as well as index them (so you can see exactly what is indexed). To do this, add an object to each index call { "store": true }. For example,
index("languages_known", doc.personal.languages_known[c], { "store": true });
Now, when you query the index it will return a list of fields which were stored with each match.

Resources