Use ParseQuery to get the first item found from list - parse-platform

I want to query Parse in order to retrieve the first object found in a given list, in the given list's order.
My code looks pretty much like this:
query = getQuery(MyClass.class).whereContainedIn("FieldName", itemList);
networkQuery.getFirstInBackground(...);
What I need, specifically, is to retrieve the first item found in the list, meaning that if I provide it a list of numbers in ascending order, I wish to retrieve the object corresponding with the smallest number possible.
I'm not sure this is how getFirstInBackground() works, I know it fetches a single result, but how can I assure the search is made according to the order of the list I provided as argument?

You have to order your query using the -orderByAscending (or Descending, i can't remember) method. It takes the column name parameter.
So something simple and easy to understand (but I'm sure you've understood already) is to order by ascending "Age" (example), and your first result in the array will be the smallest Age.
Once your query is ordered, just set a -limit to it. It's the number of results the query will return, if you only want the five firsts, set a limit of 5. or 20. The maximum is 1000.
If you also would like to skip the 3 first results because you know they're not interesting (and I'm just elaborating out of your question's scope here), you can use the -skip method, to skip the first X results.
This should do the trick to build your query. Set all those parameters and then execute your query and you'll have correct results.
EDIT : After re-reading your question I'm not sure I'm answering what you're asking. Please elaborate if I'm not.

Find the minimum value in itemList yourself, and qualify the query with that using equalTo.
// is this javascript? if so, underscorejs is very useful
var _ = require('underscore');
var minItem = _.min(itemList); // you can add an optional iteratee function that can minimize any computation over the list
query.equalTo("FieldName", minItem);
query.getFirstInBackground(...);
Edit
Parse.Query ordering applies only to sortable types, like strings and numbers. The ordering hoped for in the question is on the min() value of an array attribute. If such a thing were available, then a getFirst query would work.
What you need can still be done with find(). Since a small number of rows will have FieldName values contained in itemList, you can just do a find() and pick out the minimum from those few results...
query.find().then(function(results) {
return _.min(results, function(result) {
return result.get("FieldName");
});
});

Related

Is it possible to have a constant value in a calculated field in QuickSight?

In QuickSight, when you want to define a constant value to reuse it in visualizations later, you can try to set it as:
Calculated field: goalFor2020
Formula: 20000
But right now it doesn't allow you to put just a number in the formula.
Is there any way to do achieve having just a number in the formula of a calculated field?
The reason we need it is just to have a number that doesn't depend on any data, just manually defined by us.
Interesting, QuickSight lets me insert a number into a calculated field, just fine.
Since that isn't working for you, I'd recommend using a parameter with a default value. For example,
Parameters essentially has the same "rights" as a calculated field (it can be used in visuals, other calculated fields, etc...). It can also be passed via query parameters which may or may not be a feature that you'd find useful.
Another cool benefit of using parameters is that, if you're embedding QuickSight, you could retrieve this value dynamically and pass it to the dashboard. Then if you wanted to, say, generalize your for different yearly goals, the goal could be passed and dynamic (rather than hard-coded in a calculated field).
We could achieve it with a trick, just apply some function that returns a number to one of your columns, and make it 0, then add your constant number:
Calculated field: goalFor2020
Formula: count(email) * 0 + 20000
It does the trick, but there might be a better way to do it.
I have tried something like this:
distinct_countIf({dimension},{dimension}='xxx')*
+distinct_countIf({dimension},{dimension}='xxx')*
just makes the discount_countif meet the requirement, so it will return to 1. And use 1* the number you want to hardcode. If the requirement does not meet, it will return 0 so it won't add up the number

Sorting a table that another excel sheet uses causes different VLOOKUP results

I'm creating a dashboard in Excel 2010 that uses the VLOOKUP function to call another sheet's values.
The equation I'm using is this:
=VLOOKUP(L$1,Sheet_B!$A:$H,7,2)
L$1 asks for a unique identifier on Sheet_A, and then finds that ID on Sheet_B and then finds the corresponding data and pulls it.
The problem is this:
If I do nothing to Sheet_B, I'll get a value - let's say 5. This value is incorrect.
If I sort Sheet_B from A-Z alphabetically (which doesn't change the data) I'll get a totally different value - let's say 12 - which is the correct value.
The problem is that the data that the VLOOKUP function examines hasn't changed, only how it was sorted in Sheet_B.
Is there any reason why this might happen? And more importantly, how can I fix it so I don't have to keep sorting Sheet_B every time I pull this dashboard?
If your 4th parameter equals True (2 in your case), VLOOKUP tries to find an approximate match, so you need the values in the first column of table_array to be placed in ascending order.
If you change it to 0 (equivalent to False), VLOOKUP will try to find an exact match, and so will not need to be sorted.
Therefore, you should change your VLOOKUP to:
=VLOOKUP(L$1,Sheet_B!$A:$H,7,0)
You can read more in this Microsoft Office Support article..

Concatenating a LINQ query and LINQ sort statement

I'm having a problem joining two LINQ queries.
Currently, my (original) code looks like this
s.AnimalTypes.Sort((x, y) => string.Compare(x.Type, y.Type));
What I'm needing to do is change this based on a date, then select all data past that date, so I have
s.AnimalTypes.Select(t=>t.DateChanged > dateIn).ToList()
s.AnimalTypes.Sort((…
This doesn't look right as it's not sorting the data selected, rather sorting everything in s.AnimalTypes.
Is there a way to concatenate the two LINQ lines? I've tried
s.AnimalTypes.Select(t=>t.DateChanged > dateIn).ToList().Sort((…
but this gives me an error on the Sort section.
Is there a simple way to do this? I've looked around and Grouo and OrderBy keep cropping up, but I'm not sure these are what I need here.
Thanks
From your description, I believe you want something like:
var results = s.AnimalTypes.Where(t => t.DateChanged > dateIn).OrderBy(t => t.Type);
You can call ToList() to convert to a List<T> at the end if required.
There are a couple of fundamental concepts I believe you are missing here -
First, unlike List<T>.Sort, the LINQ extension methods don't change the original collections, but rather return a new IEnumerable<T> with the filtered or sorted results. This means you always need to assign something to the return value (hence my var results = above).
Second, Select performs a mapping operation - transforming the data from one form to another. For example, you could use it to extract out the DateChanged (Select(t => t.DateChanged)), but this would give you an enumeration of dates, not the original animal types. In order to filter or restrict the list with a predicate (criteria), you'd use Where instead.
Finally, you can use OrderBy to reorder the resulting enumerable.
You are using Select when you actually want to use Where.
Select is a projection from one a collection of one type into another type - you won't increase or reduce the number of items in a collection using Select, but you can instead select each object's name or some other property.
Where is what you would use to filter a collection based on a boolean predicate.

couchdb - retrieve unique documents for a view that emits non-unique two array keys

I have an map function in a view in CouchDB that emits non-unique two array keys, for documents of type message, e.g.
The first position in the array key is a user_id, the second position represents whether or not the user has read the message.
This works nicely in that I can set include_docs=true and retrieve the actual documents. However, I'm retrieving duplicate documents in that case, as you can see above in the view results. I need to be able to write a view that can be queried to return unique messages that have been read by a given user. Additionally, I need to be able to efficiently paginate the resultset.
notice in the image above that [66, true] is emitted twice for doc id 26a9a271de3aac494d37b17334aaf7f3. As far as I can tell, with the keys in my map function, I cannot reduce in such a way that unique documents will be returned.
the next idea I had was to emit doc._id also in the map function and reduce with group_level=exact the result being:
now I am able to get unique document ids, but I cannot get the documents without doing a second query. And even in the case of a second query, it will require a lot of complexity to do pagination like this (at least I think so).
the last idea I came up with is to emit the entire document rather than the doc._id in the third position in the array key, then I can access the entire document and likely paginate. This seems really brutish.
So my question is:
Is #3 above a terrible idea? Is there something I'm missing? Is there a better approach?
Thanks in advance.
See #WickedGrey's comment to the question. The solution is to ensure that I never emit the same key twice for one document. I do this in the map function by keeping track of the keys as I emit them in an array, then skipping the emit if the key exists in the array.

Salesforce SOQL query length and efficiency

I am trying to solve a problem of deleting only rows matching two criteria, each being a list of ids. Now these Ids are in pairs, if the item to be deleted has one, it must have the second one in the pair, so just using two in clauses will not work. I have come up with two solutions.
1) Use the two in clauses but then loop over the items and check that the two ids in question appear in the correct pairing.
I.E.
for(Object__c obj : [SELECT Id FROM Object__c WHERE Relation1__c in :idlist1 AND Relation2__c in:idlist2]){
if(preConstructedPairingsAsString.contains(''+obj.Relation1__c+obj.Relation2__c)){
listToDelete.add(obj);
}
}
2) Loop over the ids and build an admittedly long query.
I like the second choice because I only get the items I need and can just throw the list into delete but I know that salesforce has hangups with SOQL queries. Is there a penalty to the second option? Is it better to build and query off a long string or to get more objects than necessary and filter?
In general you want to put as much logic as you can into soql queries because that won't use any script statements and they execute faster than your code. However, there is a 10k character limit on soql queries (can be raised to 20k) so based on my back of the envelope calculations you'd only be able to put in 250 id pairs or so before hitting that limit.
I would go with option 1 or if you really care about efficiency you can create a formula field on the object that pairs the ids and filter on that.
formula: relation1__c + '-' + relation2__c
for(list<Object__c> objs : [SELECT Id FROM Object__c WHERE formula__c in :idpairs]){
delete objs;
}

Resources