I am trying to sort a model in Ember by a field that has a transform. The original field is an IntegerField (served by an API), which is ordered appropriately. When the field is deserialized by the transform into the string representation, ember sorts by the string, as opposed to the original order.
For instance, if this is the deserialization:
{
10: 'Built',
20: 'Started',
30: 'Finished',
};
I want this to appear as Built, Started, Finished when sorted, according to the original enum. However, it will actually be sorted as Built, Finished, Started, per the alphabetized strings.
Is this possible when using Ember.computed.sort?
i know it is not what you want, but after many search i just do this type of sort on the ember
var sortArray = Ember.ArrayProxy.extend(Ember.SortableMixin).create();
sortArray.set("content", []);
sortArray.addObject({"id":10 , "name": 'Built'});
sortArray.addObject({"id":20 , "name": 'Started'});
sortArray.addObject({"id":30 , "name": 'Finished'});
sortArray.set('sortProperties', ["id"]).set("sortAscending", true);
Related
I have a field which has similar values. For eg {country : 'US'} occurs multiple times in the table. Similar for other countries too. I want to return an array which contains non-redundant values of 'country' field. I am new to creating Databases so likely this is a trivial question but I couldn't find anything useful in rethinkdb api.[SOLVED]
Thanks
You can use distinct, but the distinct command was created for short sequences only.
If you have a lot of data, you can use map/reduce
r.table("data").map(function(doc) {
return r.object(doc("country"), true) // return { <country>: true}
}).reduce(function(left, right) {
return left.merge(right)
}).keys() // return all the keys of the final document
I'm trying to build an api to create a collection in backbone. My Model is called log and has this (shortened) properties (format for getLog/<id>):
{
'id': string,
'duration': float,
'distance': float,
'startDate': string,
'endDate': string
}
I need to create a collection, because I have many logs and I want to display them in a list. The api for creating the collection (getAllLogs) takes 30 sec to run, which is to slow. It returns the same as the format as the api getLog/<id>, but in an array, one element for each log on the database.
To speed things up, I rebuild the api several times and optimize it to it's limits, but now I came to 30 sec, which is still to slow.
My question is if it is possible to have a collection filled with instances of a model without ALL the information in the model, just a part of it needed to display the list. This will increase the speed of loading the collection and displaying the list, while in the background I could continue loading all other properties, or load them only for the elements I really need.
In my case, the model would load only with this information:
{
'id': string,
'distance': float
}
and all other properties could be loaded later.
How can I do it? is it a good idea anyway?
thanks.
One way to do this is to use map to get the shortened model. Something like this will convert a Backbone.Collection "collection" with all properties to one with only "id" and "distance":
var shortCollection = new Backbone.Collection(collection.toJSON().map(function(x) {
return { id: x.id, distance: x.distance };
}));
Here's a Fiddle illustration.
Using Server side javascript, I need to sort a NotesDcumentCollection based on a field in the collection containing a date when the documents was created or any built in field when the documents was created.
It would be nice if the function could take a sort option parameter so I could put in if I want the result back in ascending or descending order.
the reason I need this is because I use database.getModifiedDocuments() which returns an unsorted notesdocumentcollection. I need to return the documents in descending order.
The following code is a modified snippet from openNTF which returns the collection in ascending order.
function sortColByDateItem(dc:NotesDocumentCollection, iName:String) {
try{
var rl:java.util.Vector = new java.util.Vector();
var tm:java.util.TreeMap = new java.util.TreeMap();
var doc:NotesNotesDocument = dc.getFirstDocument();
while (doc != null) {
tm.put(doc.getItemValueDateTimeArray(iName)[0].toJavaDate(), doc);
doc = dc.getNextDocument(doc);
}
var tCol:java.util.Collection = tm.values();
var tIt:java.util.Iterator = tCol.iterator();
while (tIt.hasNext()) {
rl.add(tIt.next());
}
return rl;
}catch(e){
}
}
When you construct the TreeMap, pass a Comparator to the constructor. This allows you to define custom sorting instead of "natural" sorting, which by default sorts ascending. Alternatively, you can call descendingMap against the TreeMap to return a clone in reverse order.
This is a very expensive methodology if you are dealing with large number of documents. I mostly use NotesViewEntrycollection (always sorted according to the source view) or view navigator.
For large databases, you may use a view, sorted according to the modified date and navigate through entries of that view until the most recent date your code has been executed (which you have to save it somewhere).
For smaller operations, Tim's method is great!
I've decided to give Dojo a shot instead of using JQuery for once, and am having trouble manipulating a data store. I've got a DataChart bound to the contents of an ItemFileWriteStore i've populated by hand from a web socket JSON message:
fakeData = {
"identifier": "name",
"label": "Some data i'd like to add to later",
"items": [
{
"name": "appendToMe",
"values": [0.0, 1.0, 2.0, 3.0, 2.0, 1.0, 0.0]
}
]
};
store = new dojo.data.ItemFileWriteStore({
data: fakeData
});
var chart = new dojox.charting.DataChart("chartDiv", {});
chart.setStore(store, {"name":"*"}, "values");
At this point, the graph is displaying the "appendToMe" series i've created. Next, I receive another message, containing some new numeric value for the "appendToMe" values list.
How do I add it to the store, and will this be sufficient to trigger the graph to update?
I've looked at the [](write API) 'store.setValue', but it looks like I can only use this to replace the whole values chunk as one unit. In addition, I don't have a 'item' handle to use with the call, which appears to only be available if you use the newItem API instead of constructing the store with JSON.
Cheers!
Scott
First you need to fetch the appendToMe item.
store.fetchItemByIdentity({identity : 'appendToMe',
onItem : function (item) {
var itemValues = store.getValues(item, 'values');
itemValues.push(someNewValue);
store.setValues(item, 'values', itemValues);
}});
Then in the onItem, get your values, modify them, and then set them again using store.setValue()
As noted, getValues needs to be used to return the array of values instead of the usual getValue, which never returns an array. And similar with setValues.
http://dojotoolkit.org/api/1.6/dojo/data/api/Read
This getValues() method works just
like the getValue() method, but
getValues() always returns an array
rather than a single attribute value.
The array may be empty, may contain a
single attribute value, or may contain
many attribute values. If the item
does not have a value for the given
attribute, then getValues() will
return an empty array: []. (So, if
store.hasAttribute(item, attribute)
has a return of false, then
store.getValues(item, attribute) will
return [].)
setValues()
http://dojotoolkit.org/api/1.6/dojo/data/api/Write
Adds each value in the values array
as a value of the given attribute on
the given item. Replaces any previous
value or values. Calling
store.setValues(x, y, []) (with
values as an empty array) has the same effect as calling
store.unsetAttribute(x, y).
Based on a great answer to my previous question, I've partially solved a problem I'm having with CouchDB.
This resulted in a new view.
Now, the next thing I need to do is remove duplicates from this view while ordering by date.
For example, here is how I might query that view:
GET http://scoates-test.couchone.com/follow/_design/asset/_view/by_userid_following?endkey=[%22c988a29740241c7d20fc7974be05ec54%22]&startkey=[%22c988a29740241c7d20fc7974be05ec54%22,{}]&descending=true&limit=3
Resulting in this:
HTTP 200 http://scoates-test.couchone.com/follow/_design/asset/_view/by_userid_following
http://scoates-test.couchone.com > $_.json.rows
[ { id: 'c988a29740241c7d20fc7974be067295'
, key:
[ 'c988a29740241c7d20fc7974be05ec54'
, '2010-11-26T17:00:00.000Z'
, 'clementine'
]
, value:
{ _id: 'c988a29740241c7d20fc7974be062ee8'
, owner: 'c988a29740241c7d20fc7974be05f67d'
}
}
, { id: 'c988a29740241c7d20fc7974be068278'
, key:
[ 'c988a29740241c7d20fc7974be05ec54'
, '2010-11-26T15:00:00.000Z'
, 'durian'
]
, value:
{ _id: 'c988a29740241c7d20fc7974be065115'
, owner: 'c988a29740241c7d20fc7974be060bb4'
}
}
, { id: 'c988a29740241c7d20fc7974be068026'
, key:
[ 'c988a29740241c7d20fc7974be05ec54'
, '2010-11-26T14:00:00.000Z'
, 'clementine'
]
, value:
{ _id: 'c988a29740241c7d20fc7974be063b6d'
, owner: 'c988a29740241c7d20fc7974be05ff71'
}
}
]
As you can see, "clementine" shows up twice.
If I change the view to emit the fruit/asset name as the second key (instead of the time), I can change the grouping depth to collapse these, but that doesn't solve my order-by-time requirement. Similarly, with the above setup, I can order by time, but I can't collapse duplicate asset names into single rows (to allow e.g. 10 assets per page).
Unfortunately, this is not a simple question to explain. Maybe this chat transcript will help a little.
Please help. I'm afraid that what I need to do is still not possible.
S
You can do this using list function. Here is an example to generate a really simple list containing all the owner fields without dupes. You can easily modify it to produce json or xml or anything you want.
Put it into your assets design doc inside the lists.nodupes and use like this:
http://admin:123#127.0.0.1:5984/follow/_design/assets/_list/nodupes/by_userid_following_reduce?group=true
function(head, req) {
start({
"headers": {
"Content-Type": "text/html"
}
});
var row;
var dupes = [];
while(row = getRow()) {
if (dupes.indexOf(row.key[2]) == -1) {
dupes.push(row.key[2]);
send(row.value[0].owner+"<br>");
}
}
}
Ordering by one field and uniquing on another isn't something the basic map reduce can do. All it can do is sort your data, and apply reduce rollups to dynamic key-ranges.
To find the latest entry for each type of fruit, you'd need to query once per fruit.
There are some ways to do this that are kinda sane.
You'll want a view with keys like [fruit_type, date], and then you can query like this:
for fruit in fruits
GET /db/_design/foo/_view/bar?startkey=["apples"]&limit=1&descending=true
This will give you the latest entry for each fruit.
The list operation could be used to do this, it would just echo the first row from each fruit's block. This would be efficient enough as long as each fruit has a small number of entries. Once there are many entries per fruit, you'll be discarding more data than you echo, so the multi-query approach actually scales better than the list approach, when you get to a large data set. Luckily they can both work on the same view index, so when you have to switch it won't be a big deal.