Access value based on value of other key in object? - handlebars.js

This is (hopefully) a simple solution but I cannot figure it out.
I have an array of objects and I need to access a value by specifying the value of another key.
[{ category_id: 14, description: 'AMAZON DIGITAL' },
{ category_id: 15, description: 'AMAZON DIGITAL SER' }]
Basically, I want to get "AMAZON DIGITAL" when the category_id is 14. Ideally, without using a loop.

Related

Firestore: How to order by dynamic keys

I'm building a program in Angular/Firestore that will allow users to create forms with questions, (similar to typeform) and then other people can fill out those questions.
The issue I'm having is that admin needs to be able to filter by the dynamically created question answer values.
Here is an example of the data structure:
Form collection:
{
id: 123,
questions: [
{
id: 0,
value: "How many students did you teach today?"
},
{
id: 1,
value: "What school were you at?"
},
{
id: 2,
value: "What was the date?"
},
]
}
UserSubmissions
{
formId: 123,
questions: [
{
id: 0,
value: 10
},
{
id: 1,
value: 'Random school name'
},
{
id: 2,
value: 2021/07/12
},
]
}
So let's say we had 100 form submissions and admin wanted to order by how many students were taught, how could I do something like .orderBy("formSubmissions.questions[0].value") or .orderBy(formSubmissions.questions.0.value").
The second one works, but there would need to be a composite index created for an unknown amount of questions. I could technically have it so you can only order by the first 10 questions or something but I feel like there has to be a better way to doing this. I don't mind restructuring data if I have to.
If you want to order on specific questions, consider creating a subcollection of questions under each form submission. Trying to order/filter on specific array elements is going to either be difficult, not scale beyond 10 items, or both.

Hot to improve a query based on a nested object

I'm using AWS DynamoDB to store data in JSON format. The Partition key is "device" and sort key is "timestamp". I can query the table for a specific device in a range of dates. I can then filter the content by the specific endpoint (in the nested "reports" object) the application is interested in.
{
"device": "AAA111",
"attr1": "bbb",
"reports": [
{
"endpoint": 1,
"value": "23"
},
{
"endpoint": 3,
"value": "26"
},
{
"endpoint": 4,
"value": "20"
}
],
.........
............
...........
"timestamp": "2017-11-30T03:50:30z"
}
The problem I have is if for example, I want to retrieve the latest value of an specific "endpoint". So, I can retrieve the latest record for a "device" based on the latest "timestamp", but it doesn't guarantee this record will contain value for this particular endpoint (not all records contains all endpoints). To solve this I have to basically scan the latest records (in descending order) and return the first object where the endpoint is found. Also, I don't know how many records I have to retrieve to find one...
I'm wondering if there is a better way of doing this... I tried with secondary indexes but this would require to duplicate the data, creating an object for each endpoint value (duplicating the common data). I would like to avoid this...
I would appreciate any hints on how to solve this issue.
Thanks
Gus

can getstream aggregation work on properties of the "object" property

I set up the aggregation rule:
{{ object.experienceId }}
on a notification feed in getstream.io expecting it to aggregate based on the object.experienceId, but instead it seems to aggregate everything into one, regardless of object.experienceId. Am I mis-understanding how aggregation works? What could be the issue?
var activity = {
time: new Date(),
verb: 'created',
actor: { id: 1, name: 'User One' },
object: {
id: 2,
experienceId: 12,
caption: 'Moment 1',
photo:
{ id: '314e00a2-2455-11e5-b696-feff819cdc9f',
mainColor: 'ff3333',
width: 1000,
height: 400 },
createdBy: {
id: 1, name: 'User One'
},
type: 'Moment' },
context: 'http://derbyapp.co'
};
notifications.addActivity(activity,
The reason why this is not working is because the object field is expected to be a string (http://getstream.io/docs/#add-remove-activities), thus within the aggregation rule you can not reference properties of activities object field. There are multiple solutions to this problem.
First you could supply the experienceId as a separate property of the activity object, so you can use the aggregation template {{ experienceId }}, since all the additional properties provided to an activity can be used in the aggregation rule (http://getstream.io/docs/#aggregated-feeds).
Second you could supply an object on any additional field of the activity, for instance item. Additional fields can reference their child properties thus you could use aggregation rule {{ item.experienceId }}. But beware not to send data to the getstream.io API that is not actually needed at getstream.io's end, in this example you could also send the object's id field, instead of the entire object, and retrieve the object from your local database once you retrieve activities from the API (The same holds for the actor field). If you do not want to take care of the logic needed for this you could use one of getstream's integration libraries (there are libraries for rails/django/laravel etc.).
var activity = {
time: new Date(),
verb: 'created',
actor: 1,
object: '1',
experienceId: 12
};

Freebase MQL - Don't show parent object if a value in array element is present?

Trying to get some movies and their genres but leave out any records that contain the genre "Thriller" in the array of genres.
How do I not only ignore the genre key itself for "Thriller", but squelch that entire movie result? With my current query, Thriller is removed from the array of genres, but the parent object (film) is still displayed.
Here's my current workup in the query editor:
http://tinyurl.com/d2g54lj
[{
'type':'/film/film',
'limit':5,
'name':null,
'/film/film/genre': [],
'/film/film/genre!=': "Thriller",
}]​
The answer provided is correct, but changes some other stuff in the query too. Here's the direct equivalent to the original query:
[{
"type": "/film/film",
"limit": 5,
"name": null,
"genre": [],
"x:genre": {"name":"Thriller",
"optional":"forbidden"},
}]​
The important part is the "optional":"forbidden". The default property used is "name", but we need to specify it explicitly when we use a subclause (to allow us to specify the "optional" keyword). Using ids instead of names, as #kook did, is actually more reliable, so that's an improvement, but I wanted people to be able to see the minimum necessary to fix the broken query.
We can abbreviate the property name to "genre" from "/film/film/genre" since "type":"/film/film" is included (we also never need to use /type/object for properties like /type/object/name).
Answering my own question.
So the trick is to not use the != (but not) operator, but to actually flip it on its head and use the "|=" (one of) operator with 'forbid', like so:
[{
'type':'/film/film',
'limit':5,
'name':null,
'/film/film/genre': [{
"id": null,
"optional": true
}],
"forbid:/film/film/genre": {
"id|=": [
"/en/thriller",
"/en/slapstick"
],
"optional": "forbidden"
}
}]​
Thanks to the following post:
Freebase query - exclusion of certain values

Eliminating MQL results on any_reverse reflection

I'm trying to get all events in a geo bounding box (that approximately covers France), but I want to exclude all recurring events, so I don't get heaps of French Tennis opens and the like. For this I used the following in my query.
"/time/event/instance_of_recurring_event": {
"id": null,
"optional": "forbidden"
}
However, I've noted Cannes film festivals appear (the individual events for each year), because they do not have the instance_of_recurring_event property set. I can however see that the Recurring Event "Cannes Film Festival" has links to the 2006, 2007, 2008 (etc) film festival events, so I thought I might be able to eliminate them using some reflection. What I have so far is:
[{
"name": null,
"id": null,
"/time/event/instance_of_recurring_event": {
"id": null,
"optional": "forbidden"
},
"/time/event/locations": [{
"geolocation": {
"latitude>": 43.2,
"latitude<": 49.68,
"longitude>": -5.1,
"longitude<": 7.27
}
}],
"/type/reflect/any_reverse": [{
"id": null,
"estimate-count": null,
"name": null,
"/time/recurring_event/current_frequency": null
}]
}]​
This allows me to see that the 2008 Cannes film festival is linked to by the Cannes Film Festival subject (that has a yearly recurrence), but I don't know if there's any way to use that to eliminate the 2008 Cannes film festival from my list. Does that make sense?
Try here for the query editor.
Thanks for any help!
Try this: http://tinyurl.com/3okuuzw
A couple of changes:
I added the type: /time/event so that you 'll only get objects of that type. In your query, you were not restricting by type, and in Freebase, you can assert a property on an object without the type. This is a minor change and probably won't have a big effect.
The /film/film_festival_event type of which the Cannes festival is one has a property /film/film_festival_event/festival pointing to the festival series.
I added a clause at the end of the query to exclude objects that have that property set with the assumption that they are recurring events.
This will only work for film festivals, but you can re-use the same pattern for other properties.
[{
"name": null,
"mid": null,
"type" :"/time/event",
"/time/event/instance_of_recurring_event": {
"id": null,
"optional": "forbidden"
},
"/time/event/locations": [{
"geolocation": {
"latitude>": 43.2,
"latitude<": 49.68,
"longitude>": -5.1,
"longitude<": 7.27
}
}],
"/film/film_festival_event/festival": [{
"mid": null,
"optional": "forbidden",
"limit" : 0
}]
}]​
Some additional points:
a. You should use "mid" instead of "id" if you want to store the identifiers in your db or re-use them in any way later. mid is a stronger identifier than id since it survives merges and other data transformations. It's also faster to ask for mid instead of id - actually makes a big difference when the result set is large.
b. "limit" : 0 says "don't return this clause at all in the results". I think you still need the mid because you have to have at least one property in a clause that has other directives (limit and optional in this case).

Resources