Searching via attributes in Ember-Data - ember.js

With Ember-Data, it's possible to find a model instance by its id:
App.Person.find(1)
What if you want to find a model instance by another attribute, such as token. Is it possible to do something like:
App.Person.find_by(token: "ASDFGASDFASDF")
If so, should we be concerned about indexing searchable columns. How would that be done?

Your ArrayController should have a findBy method, which will return the first child element that matches your query. Alternatively you could use filterBy, which returns all elements that match.
As for indexing, that's something you might want to look at to increase performance, but that would be done on your server and depends on your setup.

Related

Iterate over an ember model query

this.store.findAll('game').then(function(results){
// RUN SOME OPERATION ON THEM
})
I would like to know how I can play with the results variable. I understand I can do
results.get('firstObject') // returns the first object.
I'd like to know everything else I can do with it. Is there any api documentation for the results collection?
Thanks!
From ember guides,
The below methods, will return the Promise, it will be resolved to Record or RecordArray.
store.findAll() returns a DS.PromiseArray that fulfills to a DS.RecordArray.
store.findRecord returns a promise that will be resolved with the record.
store.query() returns a DS.PromiseArray in the same way as findAll.
The below two are synchronus method, it will retrieve what is available in the store and returns record itself. it will not request the server to fetch data.
store.peekAll directly returns a DS.RecordArray.
store.peekRecord direclty returns record
It's important to note that DS.RecordArray is not a JavaScript
array, it's an object that implements Ember.Enumerable. This is
important because, for example, if you want to retrieve records by
index, the [] notation will not work--you'll have to use
objectAt(index) instead.
From Ember.Enumerable, most of the time I happened to use the following,
forEach to iterate
map to transform to new Array
filterBy findBy for filtering based on single property check
toArray converting to normal native array
findAll will return a Promise which will resolve to a RecordArray.
The RecordArray is an ArrayProxy.
http://emberjs.com/api/classes/Ember.ArrayProxy.html
This is everything you need.
If you google "ember findall" you will find docs for "Ember.js - Models: Finding Records - Guides" as well.
https://guides.emberjs.com/v2.5.0/models/finding-records/

Most Efficient Way to get the "id" of the first record in Rails

I'm reviewing some code and I came across a line that does the following:
Person.find_by(name: "Tom").id
The above code gets the FIRST record with a name of "Tom", then builds a model, then gets the id of that model. Since we only want the id, the process of retreiving all data in the model and initializing the model is unneeded. What's the best way to optimize this using active record queries?
I'd like to avoid a raw sql solution. So far I have been able to come up with:
Person.where(name: "Tom").pluck(:id).first
This is faster in some situations since pluck doesn't build the actual model object and doesn't load all the data. However, pluck is going to build an array of records with name "Tom", whereas the original statement only ever returns a single object or nil - so this technique could potentially be worse depending on the where statement. I'd like to avoid the array creation and potential for having a very long list of ids returned from the server. I could add a limit(1) in the chain,
Person.where(name: "Tom").limit(1).pluck(:id).first
but is seems like I'm making this more complicated than it should be.
With Rails 6 you can use the new pick method:
Person.where(name: 'Tom').pick(:id)
This is a little verbose, but you can use select_value from the ActiveRecord connection like this:
Person.connection.select_value(Person.select(:id).where(name: 'Tom').limit(1))
This might work depending on what you're looking for.
Person.where(name: "Tom").minimum(:id)
Person.where(name: "Tom").maximum(:id)
These will sort by id value while the Person.where(name: "Tom").first.id will sort off of your default sort. Which could be id, created_at, or primary_key.
eitherway test and see if it works for you

How to add multiple nodes to relations

How to add multiple node to relations here is my query
MATCH (n:Customer{name:"motoM"})-[:RECENT {default:TRUE}]-(l:Location{name:"Adugodi"}) return l how to write a query to add one more "location" node to the relation "recent" if location node is not found and setting default to true to newly created realtion
What about this?
MATCH (n:Customer{name:"motoM"})-[:RECENT {default:TRUE}]-(l:Location{name:"Adugodi"})
MERGE (n)-[:RECENT]->(l2:Location)
ON CREATE SET l2.default = true
RETURN l, l2
The direction needs to be specified so I made it up, but it might need to go the other way.
Well, I don't know if I understood what you were looking for, but this might help you :)
Try with this query:
MATCH (n:Customer{name:"motoM"})-[r:RECENT {default:TRUE}]-(:Location{name:"Adugodi"})
CREATE (l2:Location{name:"Wherever You need"})
With r,n,l,l2
Set r.default = false
With n,l2
CREATE (n)-[r2:RECENT{default:TRUE}]->(l2)
I'm using Withto make the query easier to read, but you can do it in a single query.
In fact, I think your problem is your Graph model.
You should probably do something like a Customer node, related to Location nodes with a "VISITED" relation, and when you create your VISITED relation, you set date property to timestamp. Then, when you get your relations, you can simply compare timestamps to get the closest one, and you know which one is the one your need. Also, if you need a default property, set it on the node, it'll be easier to match.
Tell me if you need a code example for match, create and set data with this graph model.

Find model returns undefined when trying to get the attribute of a model by first finding the model by another attribute?

I would like to do something like:
App.Model.find({unique_attribute_a: 'foo'}).objectAt(0).get('attribute_b')`
basically first finding a model by its unique attribute that is NOT its ID, then getting another attribute of that model. (objectAt(0) is used because find by attribute returns a RecordArray.)
The problem is App.Model.find({unique_attribute_a: 'foo'}).objectAt(0) is always undefined. I don't know why.
Please see the problem in the jsbin.
It looks like you want to use a filter rather than a find (or in this case a findQuery). Example here: http://jsbin.com/iwiruw/438
App.Model.find({ unique_attribute_a: 'foo' }) converts the query to an ajax query string:
/model?unique_attribute_a=foo
Ember data expects your server to return a filtered response. Ember Data then loads this response into an ImmutableArray and makes no assumption about what you were trying to find, it just knows the server returned something that matched your query and groups that result into a non-changable array (you can still modify the record, just not the array).
App.Model.filtler on the other hand just filters the local store based on your filter function. It does have one "magical" side affect where it will do App.Model.find behind the scenes if there are no models in the store although I am not sure if this is intended.
Typically I avoid filters as it can have some performance issues with large data sets and ember data. A filter must materialize every record which can be slow if you have thousands of records
Someone on irc gave me this answer. Then I modified it to make it work completely. Basically I should have used filtered.
App.Office.filter( function(e){return e.get('unique_attribute_a') == 'foo'}).objectAt(0)
Then I can get the attribute like:
App.Office.filter( function(e){return e.get('unique_attribute_a') == 'foo'}).objectAt(0).get('attribute_b')
See the code in jsbin.
Does anyone know WHY filter works but find doesn't? They both return RecordArrays.

django queryset ordering

I'm listing queryset results and would like to add an option for choosing the order results are displayed.
I would like to pass the actual data from the database to other page for sorting.
I was able to achieve such thing by getting all objects ids and use django session to recreate a new queryset based on the order criteria.
I was thinking if there is any other way to achieve such goal?
10x
Assuming you are currently displaying the data as a table, you could give chance to some javascript client side table sorter such as tablesorter. There are lots of javascript table sorte.
I'm away from my development machine right now, but I think you could just pass the list of ids to a new Queryset, pk__in=list_of_object_ids, and then use the native order_by function.
For example:
objs = Object.objects.filter(pk__in=list_of_object_ids).order_by('value_to_order_by')
Anyway, that's what I would try first, though I'm sure there are better optimizations.
For example, instead of a list of object ids, you could pass a dictionary with a key:value pair that has the value you want to order by.
For example:
[{'obj_id':1,'obj_value':'foo'},{'obj_id':2,'obj_value':'foo'}]
Then use some lambda function to sort it, like here.