Parse.com : Query Max Value of Column in JS API - javascript

If in sql, we can get it with:
select Max(Column_name) from Table_name
but still can't find simple way to get Max value of Column in Parse.com JS API.
Please explain me how to get Max Value of Column in JS API?

The best way to do this is to use Parse.Query (api) and order by descending, then obtain the first item in the result.
Edit:
Maybe, it's not a good idea to use order by in the situation that there are thousands(or even more) items as it's time consuming(complexity at least O(nlogn)). An alternative is to write a function of your own to choose the maximum value yourself with complexity of O(n).

Write a query for descending order and fetch the first object out of it. You will have the max value of the column there.
var query = new Parse.Query("something");
query.descending("column_name");
query.first({
success: function(result){
var max = result.get("column_name");
},
error: function(){
},
})

I am not sure if you can do it directly with a max function. You can create your own max function by doing a query to get all entries from that column and sorting them in descending order. There are APIs for this. Then choose the first value from the sorted list.

You can basically follow the same pattern from all other queries:
// Query for ID
ParseQuery<ParseObject> query = ParseQuery.getQuery("Table_Name");
// Condition
query.orderByDescending("ID");
// First object will be retrieved, this will be the max_value
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (object == null) {
Log.d("score", "The getFirst request failed.");
} else {
Log.d("score", "Retrieved the object.");
}
Now you can get the value using something like:
String mensagem = object.getString("ID");
Hopefully this will help you!

Related

How to output the firebase snapshot in reverse order?

I am trying to get the latest 3 data from the database and display them in reverse order in the HTML page.
Code:
var refForevent = database.ref('/events/post');
refForevent.orderByChild("intro").limitToLast(3).on('child_added', function(snapshot){
var eventlist = []
eventlist.push(snapshot)
console.log(eventlist)
eventlist.reverse()
document.getElementById("event1date").innerHTML = moment(eventlist[0].intro).format("MMM Do YYYY");
document.getElementById("event1title").innerHTML = eventlist[0].title;
document.getElementById("event2date").innerHTML = moment(eventlist[1].intro).format("MMM Do YYYY");
document.getElementById("event2title").innerHTML = eventlist[1].title;
document.getElementById("event3date").innerHTML = moment(eventlist[1].intro).format("MMM Do YYYY");
document.getElementById("event3title").innerHTML = eventlist[1].title;
})
Output: Output that I am getting
Database:
I see that the field intro contains a date.
Here is one solution:
Take the value of this field
Remove the hyphen separators (e.g. from 2020-12-10 you get the number 20201210)
Multiply this number by -1
Store the resulting value in another field
Sort on this field
Alternatively (and more elegant...), use the date to create a Timestamp, multiply it by -1 and use it as explained above, i.e. store the resulting value in another field and sort on this field.
Since you're listening to the child_added event, your function gets called with each post node that matches the query in the order in which Firebase returns them. So your eventlist will only ever contain one node at a time.
To reverse the items, you can either get Firebase to return the values in reverse order, as Renaud suggest (I'll also link some answers below), or you can listen to all results in once go and then reversing client-side (as your code already seem to be trying). The latter would look something like:
var refForevent = database.ref('/events/post');
refForevent.orderByChild("date").limitToLast(3).on('value', function(results){
var eventlist = []
results.forEach(function(snapshot) {
eventlist.push(snapshot.val())
});
eventlist.reverse()
console.log(eventlist);
...
})
So this:
Listens to the value event, instead of child_added, so that it gets all matching child nodes in one go.
If then loops over the results, adding them to the array,
It calls .val() on each child snapshot, to get the value from it.
For more on descending sorting, also see:
Display posts in descending posted order (the oldest I could find describing the trick with negative values)
firebase -> date order reverse (with many more links from there)
Sorting in descending order in Firebase database

WebdriverIO loop through element list

So I have a table of 250 of rows, and I want to just get all the values from one column and check if they meet the required criteria:
const rows = browser.elements(selector..);
const numbers = [];
rows.value.forEach(cellData => {
const value = browser.elementIdText(cellData.value.ELEMENT).value;
// some logic to check if the value is ok
numbers.push(value);
});
// check if all numbers are sorted correctly
, but it most of the time it fails on the line (it says stale element reference: element is not attached to the page document):
const value = browser.elementIdText(cellData.value.ELEMENT).value;
I tried doing cellDate.getText(), but there was a Java socket error, could someone help? I assume the selector is not attached to the page as indicated, but I can't figure my head out how to just loop through them all.
I had a solution similar to your method before and while it seems to work, I think there might just be some slight adjustments to your code to get what you want. I never had much luck chaining from the end of the elementIdText call.
Step 1: Grab all the Data (browser.elements or browser.$$):
let cellData = browser.$$('selector that matches desired Column Data')
The above returns an array of JSON WebElements. And as you know you can correctly loop through the array looking at the "values". If you use the selector that matches the Column Values you're looking for you should have all similar data stored in the element.value.ELEMENT.
Step 2: Loop through the cellData array and pluck out the text values of the ELEMENT using browser.elementIdText()
cellData.forEach((elem) => {
let number = browser.elementIdText(elem.value.ELEMENT)
//elementIdText also returns a JSON WebElement so it's number.value
if(number.value === <condition>) {
console.log('number looks good')
//perform other on value logic
}
})
//perform other logic still in loop EX: array.push()
})
I hope this helps! Let me know if you hit any snags!

How can I get integers from bigquery nodejs api?

I am fetching data from bigquery which I need to store in MongoDB as integer, so that I can perform operations on that data in Mongo. Even though the data types of columns in bigquery is Integer, its nodejs api is returning string in its Javascript object. E.g. I'm getting results that look like [{row1:'3',row2:'4',row3:'5'},{row1:'13',row2:'14',row3:'15'}...]
typeof gives string on each element of object. I can run a loop and convert each element to integer, but that is not scalable on the data set. Also, I don't want all strings to be converted to integers, only ones which are stored as integer in bigquery. I'm using gcloud module in nodejs to fetch data.
assuming you know where the type property is on the response, something like this would work.
var response = [{type: 'Integer', value: '13'} /* other objects.. */];
var mappedResponse = response.map(function(item) {
// Put your logic here
// This implementation just bails
if (item.type != 'Integer') return item;
// This just converts the value to an integer, but beware
// it returns NaN if the value isn't actually a number
item.value = parseInt(item.value);
// you MUST return the item after modifying it.
return item;
});
This still loops over each item, but immediately bails out if it's not what we're looking for. Could also compose multiple maps and filters to generalize this out.
The only way to get by this is by first applying a filter, but this basically achieves the same thing as our initial type check
var mappedResponse = response
// Now we only deal with integers in the map function
.filter(x => x.type == 'Integer)
.map(function(item) {
// This just converts the value to an integer, but beware
// it returns NaN if the value isn't actually a number
item.value = parseInt(item.value);
// you MUST return the item after modifying it.
return item;
});
BigQuery deliberately encodes integers as strings when returning them via API to avoid loss of precision for large values. For now, the only option is to parse them on the client side.

parse.com search for partial string in array

I'm trying to search a Parse.com field which is an array for a partial string.
When the field is in String format I can do the following:
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.searchResults removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.busnumber contains[c] %#", searchText];
self.searchResults = [NSMutableArray arrayWithArray:[self.objects filteredArrayUsingPredicate:predicate]];
This works, however the new field I want to search in is an Array.
It works when I change the it to the following:
PFQuery * query = [PFQuery queryWithClassName:#"Bus"];
[query whereKey:#"route" equalTo:[NSString stringWithFormat:#"%#", searchText]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
NSLog(#"Objects: %#", objects);
if (error)
{
NSLog(#"ERROR: %#", error.localizedDescription);
}
else
{
[self.searchResults removeAllObjects];
[self.searchResults addObjectsFromArray:objects];
[self.searchDisplayController.searchResultsTableView reloadData];
}}];
However I need the exact String for this.
I want to be able to search for parts of a string though, but when I change it to:
[query whereKey:#"route" containsString:[NSString stringWithFormat:#"%#", searchText]];
I get:
[Error]: $regex only works on string fields (Code: 102, Version: 1.7.4)
Any ideas? Thanks :)
What you've attempted is rational, but the string qualifiers on PFQuery work only on strings.
I've seen this theme frequently on SO: PFQuery provides only basic comparisons for simple attributes. To do anything more, one must query for a superset and do app level computation to reduce the superset to the desired set. Doing so is expensive for two reasons: app-level compute speed/space, and network transmission of the superset.
The first expense is mitigated and the second expense is eliminated by using a cloud function to do the app level reduction of the superset. Unless you need the superset records on the client anyway, consider moving this query to the cloud.
Specific to this question, here's what I think the cloud function would resemble:
// very handy to have underscore available
var _ = require('underscore');
// return Bus objects whose route array contains strings which contain
// the passed routeSubstring (request.params.routeSubstring)
Parse.Cloud.define("busWithRouteContaining", function(request, response) {
// for now, don't deal with counts > 1k
// there's a simple adjustment (using step recursively) to get > 1k results
var query = new Parse.Query("Bus");
query.find().then(function(buses) {
var matching = _.select(buses, function(bus) {
var route = bus.get("route");
var routeSubstring = request.params.routeSubstring;
return _.contains(route, function(routeString) {
return routeString.includes(routeSubstring);
});
});
response.success(matching);
}, function(error) {
response.error(error);
});
});
If you do decide to perform the reduction on the client and need help with the code, I can edit that in. It will be a pretty simple switch to predicateWithBlock: with a block that iterates the array attribute and checks rangeOfString: on each.

Taffydb dynamic like 'and' query

I recently started working with taffydb. Assuming I have this as my data
db= TAFFY([
{OrderNo:'prod1',range: 3,description:'one two'},
{OrderNo:'prod2',range: 2,description:'one two three'},
{OrderNo:'prod3',range: 2,description:'one three two'},
{OrderNo:'prod4',range: 6,description:'one two four three'},
{OrderNo:'prod5',range: 5,description:'three'},...
if I wanted to write a query to find all records with "one two" and "three" I'd do something like
db({description:{likenocase:"one two"}},{description:{likenocase:"three"}}).get()
this would return products 2 and 4. Unfortunately I can't figure out how to do this with a dynamic query that will have an unknown number of variables to search for. I'm doing this to let the user search for their own supplied words.
Anyone got any ideas?
As a precursor, this will not be the best answer to your problem. But it will work. :)
So the user will have the option of searching a database with an "unknown number of variables". Let's add a maximum amount of variables--perhaps 10?
Now we catch all the user's search variables in an array:
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
userSearchVars.push( $(this).val());
}
// Note: by default an empty input will return the empty string: ""
Using your code snippet, just query the database with the array:
db(
{description:{likenocase:userSearchVars[0]}},
{description:{likenocase:userSearchVars[1]}},
{description:{likenocase:userSearchVars[2]}},
{description:{likenocase:userSearchVars[3]}},
{description:{likenocase:userSearchVars[4]}},
{description:{likenocase:userSearchVars[5]}},
{description:{likenocase:userSearchVars[6]}},
{description:{likenocase:userSearchVars[7]}},
{description:{likenocase:userSearchVars[8]}},
{description:{likenocase:userSearchVars[9]}}
).get()
Adapting #Jacob-IT's answer so that its dynamic. Used Taffy for the first time tonight and just discovered you can pass an array of objects as the query argument.
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
// This is my edit - push the whole query on to the array.
userSearchVars.push({description:{likenocase: $(this).val() }});
}
// Then pass the whole query array in...
db( userSearchVars ).get()
Tested the above - and it worked for me.
You can do it like this
let items = [];
items.push({description:{likenocase:"one two"}});
items.push({description:{likenocase:"three"}});
db(...items).get()

Categories

Resources