Mongoid query with AND and OR condition - mongodb

I am using a MongoDB for a new app I am creating and I only need certain data from it. I require the following fields: current (boolean), position, sector, and name. The position field is populated with one of four values - "cash, SPVR, OFF, and training", while the sector field has one of two values - "Break or Working". I want a query that will give me all records where the following conditions exist:
1. current = TRUE
2. Position = "SPVR" or "CASH" OR Sector = "BREAK" and
3. Name is not NULL
The problem I have is that there are hundreds of records that have a value of BREAK, but most of them do not have a value in the Name field. I don't want any records that do not have a name associated with them. So in that respect, in line 2 above, I'm guessing the OR could be AND?
This is mu current start at the Mongoid statement
get '/currentstate*' do
StateTransaction.where( current: true, :position.in =>["SPVR", "CASH"] ).to_json
end
Any help would be greatly appreciated.
Thanks!!

It should work
StateTransaction.where(current: true, :name.ne => ["",nil]).and(
StateTransaction.or(
{:position.in =>["SPVR", "CASH"]},
{sector: "BREAK"}
).selector
)

Following is arguably simpler:
sts = StateTransaction.where(current: true, :name.ne => ["",nil])
sts.any_of(:position.in => ["SPVR", "CASH"], sector: 'BREAK')

Related

Calculate value depending on multiple conditions

I have Grp_ids feild which i need to assign "Pass" or "Fail" based on the results of measure_ids
For example : If one of the measure_ids in the group is failed, i want the whole group to be failed.
Thank you.
Define Grp_Result as MIN([Measure_Results] = "Pass")
That will be True if Measure_Results = "Pass" for every data row for your selected dimensions (Grp_Ids and Measure_is in your example). If you can have null values in your Measure_Results column and if you want to treat those nulls as a Fail, then would use instead MIN(IFNULL([Measure_Results] = "Pass"), False)
This works because Tableau treats True as greater than False. So MAX() holds if is satisfied for EVERY data row, and MAX() holds if is satisfied for ANY data row.
You can simplify a bit further by using boolean values in place of strings to begin with to represent whether a record passed or failed.
This should do the trick -
IIF({ FIXED [Grp_ids]: SUM(IIF([Measure_Results] = 'Pass',0,1)) }>0,'Fail','Pass')
Sum the failures by GRP_ID. If the sum is greater than 0 (GRP_ID contains a Fail) then Fail the entire GRP_ID.

How can I create a search with filters in Angular/Express/MongoDB?

I am trying to mimic the functionality of the right sidebar of this example for my Angular site.
I don't know what this is called, or even how to go about it on the front end or back end!
My assumption:
Create a form with values coming straight from the DB and only show the desired parameter (i.e. db.collection.find(query, {parameter: 1}) which will be called to update each time a user modifies the form. Additionally, the results would also be updated on selection (I have over 100MB of documents, returning ALL of them would be troublesome, how can I limit the number of documents returned to let's say 20 or 50 (user input?) and paginate it (1000 documents returned / 50 per page = 20 'pages')
Each input that is selected, a { 'field' : value } would be returned -- but I am not sure how to control an empty value (i.e. what if a user doesn't pick a fuel type or transmission range?)
How do I go about designing such a feature correctly?
1) In your query, use limit statement:
var options = { "limit": 20 }
collection.find({}, options).toArray(...);
2) you can validate user empty input (for eg. with express-validator):
req.checkBody('postparam', 'Invalid postparam').notEmpty()
req.getValidationResult().then(function(result) {
if (!result.isEmpty()) {
res.status(400).send('There have been validation errors: ' + util.inspect(result.array()));
return;
}
and based on result choose default value/pass error/render ask page for user

Create Cumulative Change Chart in Tableau

I have a bunch of daily change % data. I would like to calculate cumulative change, which should just be (1+change)*previous day in a chart in Tableau.
Seems simple enough right? I can do it in a few seconds in Excel, but I've tried for hours to get it to work in Tableau and cannot do it.
My thought was that I can create a column that is (1+daily change%), then try to do a compound product. However, I can't seem to get it to work.
I can't attach any files here so I pasted the data, along with a column that is "cum change", which is what I would like the calculation to be.
Thank you much in advance!
Date Daily Change Cum Change
4/1/2015 0.47% 1
4/2/2015 0.56% 1.0056
4/3/2015 -0.72% 0.99835968
4/6/2015 -0.56% 0.992768866
4/7/2015 -0.80% 0.984826715
4/8/2015 0.44% 0.989159952
4/9/2015 -0.66% 0.982631497
4/10/2015 0.99% 0.992359549
4/13/2015 0.92% 1.001489256
4/14/2015 0.73% 1.008800128
4/15/2015 0.95% 1.018383729
4/16/2015 0.42% 1.022660941
4/17/2015 0.52% 1.027978778
4/20/2015 0.02% 1.028184373
4/21/2015 0.56% 1.033942206
4/22/2015 0.35% 1.037561004
4/23/2015 -0.34% 1.034033296
4/24/2015 0.18% 1.035894556
4/27/2015 0.61% 1.042213513
4/28/2015 0.46% 1.047007695
4/29/2015 0.94% 1.056849568
Create a calculated field:
IF INDEX() = 1
THEN 1
ELSE
(1 + AVG([Daily Change])) * PREVIOUS_VALUE(1)
END
The condition checking to see if it's the first row of the partition (INDEX() = 1) is necessary to ensure that the first value of the field is a 1. After that, you can just use the self-referential PREVIOUS_VALUE() to get the previous value of this same calculation.

How can I access an attribute of a selected parameter in Tableau?

I have a list of Companies with a ROIC measure. Each Company belongs to a Segment.
I created a parameter to select a Company: [SelectedCompany], and I want to create a SET which includes all the companies except the [SelectedCompany], which are in the same [Segment] as [SelectedCompany].
My set is currently defined by this formula:
[Company] != [SelectedCompany]
I should add something like:
[Company] != [SelectedCompany]
AND
[Segment] = [SelectedCompany].[Segment]
But I don't know how to access the [Segment] attribute of the [SelectedCompany].
Just for clarification, I'm making this because I want to compare the [SelectedCompany] ROIC against the average ROIC of the other Companies in the same Segment.
I would appreciate any help on this.
Thanks a lot!
Here's a bit of a hacky way to get what you're looking for. Keep your original definition for the set:
[Company] != [SelectedCompany]
Create a calculated field:
{ FIXED [Segment] : MAX( IIF([Company] = [Parameters].[SelectedCompany], 1, 0) ) }
Then drag that field into the Filters card and filter to allow only 1's. This will filter out all Segments except for the selected company's Segment.

Cassandra: get_range_slices of TimeUUID super column?

I have a schema of Row Keys 1-n. In each row there are a variable number of supercolumns with a TimeUUID 'name'. Im hoping to be able to query this data by a time range.
Two issues have come up:
in KeyRange -> the values that I put in for 'start_key' and 'end_key' are getting misunderstood (for lack of a better term) by Thrift. Experimenting with different groups of values Im not seeing what I expect and often get back something completely unexpected.
Example: my row keys are running from 1-1000 with lots of random gaps. I put start_key = 50 and end_key = 20 .. and I get back rows with keys ranging from 99 to 414.
Example: I have a known row with key = 13. Putting this value into start_key and end_key gives me no results.
Second issue: even when I do get results the 'columns' portion of the 'keyslice' is always empty. I have checked via cassandra-cli and I know there is data.
Im using Perl as follows:
my $slice_range = new Cassandra::SliceRange();
$slice_range->{ start } = create_UUID( UUID::Tiny::UUID_TIME, "2010-12-24 00:00:00" );
$slice_range->{ finish } = create_UUID( UUID::Tiny::UUID_TIME, "2011-12-25 00:00:00" );
my $slice_predicate = new Cassandra::SlicePredicate();
$slice_predicate->{ slice_range } = $slice_range;
my $key_range = new Cassandra::KeyRange();
$key_range->{ start_key } = 13;
$key_range->{ end_key } = 13;
my $result = $client->get_range_slices( $column_parent, $slice_predicate, $key_range, $consistency_level );
print Dumper( $result );
Clearly Im misunderstanding some basic precept.
EDIT: It turns out that the Perl library Im using is not properly documented. The UUID creation was not working as advertised. I opened it up, fixed it, and now its all going a bit more as I was expecting. I can slice my supercolumns by date/time range. Still working on getting the key range portion to work.
http://wiki.apache.org/cassandra/FAQ#range_rp covers why you're not seeing what you expect with key ranges.
You need to specify a SlicePredicate that contains the actual range of what you're trying to select. The default of no column_names and no slice_range will result in the empty columns list that you see.