cloudsearch query to boost exact match on range - amazon-web-services

In a cloudsearch structured query.
I have a couple of fields I am searching on.
On field one, the user selects "2"
On field two the user selects "1"
I am wanting to run this as a range query, so that the results that are returned are -1 to +1
eg. on field one the range would be 1,3 and on field 2 it would be 0,2
What I am wanting to do is sort the results so that the results that match both field 1 and field 2 are at the top, and the rest under it.
eg. where field one=2 and field two =1 would be at the top and the rest are not in any specific order,
note: I do need to end up sorting the results by distance, so that all the exact matching results are in distance order, then all the rest are ordered by distance.
I am sure I can do this with 2 queries, just trying to make it work in one query if at all possible to lighten the load.

Say your fields are 'a' and 'b', and the specified values are a=2 and b=1 (as in your example, except I've named the fields 'a' and 'b' instead of 'one' and 'two'). Here are the various terms of your query.
Range Query
This is the query for the range a±1 and b±1 where a=2 and b=1:
q=(and (range field=a[1,3]) (range field=b[0,2]))
Rank Expression
For your rank expression, compute a distance-based score using absolute value so that scores 'a' and 'b' can't cancel each other out (like a=3,b=0 would, for example):
expr.rank1=abs(a-2)+abs(b-1)
Sort by Rank
That defined a ranking expression named rank1, which we now want to sort by, starting with the lowest values ('0' means a=2,b=1):
sort=rank1 asc
Return the Rank
For debugging purposes, you may want return the ranking score:
return=rank1
Put all those terms together and you've got your query.
Further Potentially-Useful Things
If you want to get fancy and penalize things in a non-linear way, you can use exp. For example, if you want to differentiate between 'a' and 'b' both being off by 1 vs 'a' being an exact match and 'b' being off by 2 (eg a=3,b=2 will rank ahead of a=2,b=3 even though the previous ranker would give them both a score of 2):
expr.rank1=exp(abs(a-2))+exp(abs(b-1))
And you can use boolean logic and the ternary operator to detect and prefer certain results that meet certain criteria, eg to give a big boost when 'a' and 'b' are on-target, a smaller boost when 'a' or 'b' is on target, etc (since we're sorting in low-to-high, a boost in rank is actually achieved by adding less to the result):
((a==1&&b==2)?0:100)+((a==1||b==2)?0:1000)+abs(a-1)+abs(b-2)
See http://docs.aws.amazon.com/cloudsearch/latest/developerguide/configuring-expressions.html

Related

Formula to return TRUE if Criteria Matches?

The reason I am posting this question is that combining Index and Match functions only searches for first qualifying row from top-down and I am needing to find next row up from current that matches as part of my formula.
The complete formula I am trying to construct is to return TRUE in cell "C4" if equal to the row that has the lowest value in column "A" from just above a value (nonblank) in column "C" to just before numbers in column "B" go above 55. So in this case, it would return TRUE in cell "C4" because for the blue highlighted area value 28.28 is lowest in column "A".
Secondarily not sure if INDIRECT function is best to use since I have a few hundred of these in my sheet. Is this a resource hog when I need these to calculate quickly???
I have it posted here and am posting it here because I am trying to get this to work in Sheets which I know is often different than Excel.
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_win10-mso_2016/formula-to-return-true-if-criteria-matches/02834e93-c29f-449d-ace0-98722c399e63?tm=1568399215380
perhaps like this:
=ARRAYFORMULA(IF(A1:A=MIN(FILTER(A1:A, B1:B<55)), TRUE, ))

Combine two nested IF statements with multiple criteria

I have two columns of data in "Meds" sheet...
MedContinuing AgeAtMedStop
Yes "Blank"
Yes 72.22
No "Blank"
No 72.57
"Blank" 73.85
I am writing a formula in a separate sheet to return 1 or 0 based on the following:
If MedContinuing is "Blank", do nothing
If MedContinuing is "No" and AgeAtMedStop is blank, do nothing
If MedContinuing is "Yes" and AgeAtMedStop is "Blank", return 1. If AgeAtMedStop is a number, return 0.
If MedContinuing is "No" and AgeAtMedStop is a number, return 1. Otherwise, return nothing.
I was able to write two separate functions (see below) for when MedContinuing is "Yes" or when it is "No", but I need to combine both into one formula.
When it's Yes...
=IF(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="","",
IF(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="No","",
IF(AND(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="Yes",INDEX(Meds!2:2,MATCH("AgeAtMedStop",Meds!$1:$1,0))=""),1,0)))
When it's No...
=IF(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="","",
IF(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="Yes","",
IF(AND(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="No",INDEX(Meds!2:2,MATCH("AgeAtMedStop",Meds!$1:$1,0))=""),"",
IF(AND(INDEX(Meds!2:2,MATCH("MedContinuing",Meds!$1:$1,0))="No",INDEX(Meds!2:2,MATCH("AgeAtMedStop",Meds!$1:$1,0))>0),1,0))))
EDIT: Solution
Using Peter K's logic...
=IF(INDEX(Meds!6:6,MATCH("MedContinuing",Meds!$1:$1,0))="","",
IF(AND(INDEX(Meds!6:6,MATCH("MedContinuing",Meds!$1:$1,0))="No",INDEX(Meds!6:6,MATCH("AgeAtMedStop",Meds!$1:$1,0))=""),"",
IF(AND(INDEX(Meds!6:6,MATCH("MedContinuing",Meds!$1:$1,0))="Yes",INDEX(Meds!6:6,MATCH("AgeAtMedStop",Meds!$1:$1,0))=""),1,
IF(AND(INDEX(Meds!6:6,MATCH("MedContinuing",Meds!$1:$1,0))="Yes",INDEX(Meds!6:6,MATCH("AgeAtMedStop",Meds!$1:$1,0))>0),0,
IF(AND(INDEX(Meds!6:6,MATCH("MedContinuing",Meds!$1:$1,0))="No",INDEX(Meds!6:6,MATCH("AgeAtMedStop",Meds!$1:$1,0))>0),1,"")))))
It is not entirely clear from your question why you would use INDEX and MATCH functions for such straightforward problem ?
I suggest to start with the basic nested if function :
=IF(A2="";"";IF(A2="No";IF(B2="";"";1);IF(B2="";1;0)))
You can put this function next to your two columns, and then copy to another worksheet, so the references are taken care of by Excel.
I also assume that your data is clean and correct i.e. only the 3 possible values for MedContinuing ("Yes", "No" or blank) and 2 for AgeAtMedStop (blank or a number) exist in your columns, so no IF test is needed to eliminate other possible values.
You can try this method below
I have created a helper table for the logic you require, it will help to update or extend the logic in future
Formula in cell C2 is
=INDEX($F$2:$G$4,MATCH(A2,$E$2:$E$4,0),IF(B2="Blank",1,IF(ISNUMBER(B2),2,0)))

Make =IF Function Output Numbers For "Scoring": Google Sheets

I'm am exploring methods of giving scores to different datapoints within a dataset. These points come from a mix of numbers and text string attributes looking for certain characteristics, e.g. if Col. A contains more than X number of "|", then give it a 1. If not, it gets a 0 for that category. I also have some that give the point when the value is >X.
I have been trying to do this with =IF, for example, =IF([sheet] = [Text], "1","0").
I can get it to give me 1 or 0, but I am unable to get a point total with sum.
I have tried changing the formatting of the text to both "number", "plain text", and have left it as automatic, but I can't get it to sum. Thoughts? Is there maybe a better way to do this?
FWIW - I'm trying to score based on about 12 factors.
Best,
Alex
The issue here might be that you're having the cell evaluate to either the string "0" or the string "1" rather than the number 0 or the number 1. That would explain why you're seeing the right things but the math isn't coming out right - the cell contents look like numbers, but they're really text, which the summation would then ignore.
One option would be to drop the quotation marks and write something like this:
=IF(condition, 1, 0)
This has the condition evaluate to 1 if it's true and 0 if it's false.
Alternatively, you could write something like this:
=(condition) * 1
This will take the boolean TRUE or FALSE returned by condition and convert it to either the numeric value 1 (true) or the numeric value 0 (false).

Match multiple strings using re.search within an if condition

I am writing a program to create a list from a spreadsheet based on a position value in another cell. So my code looks like
for j in xrange(1,13):
for sheet in wb.sheets():
for i in xrange(1,12*15):
team=sheet.cell(i,0)
position=sheet.cell(i,2)
games=sheet.cell(i,23)
if re.match(owner[j], str(team.value)) and (not re.findall('Defense' or 'K,' or 'KFG' or 'KKO', str(position.value))):
try:
list.append(int(games.value))
except ValueError:
list.append(0)
else:
pass
print list
list=[]
So the goal of this is to append to a list when a row matches owner in the first column, and not Defense K, KFG KKO in the position column.
Unfortunately, the values for K, KFG and KKO all show
up in my lists, but the Defense values properly do not. How can I
ensure the other filtering criteria are met?
As a side note, these positions are in amongst other bits of text so
the search() is used here instead of match().
"Defense" is a 'truthy' value, so the result of:
'Defense' or 'K,' or 'KFG' or 'KKO'
is 'Defense'.
Therefore, the condition you have is no different from:
re.match(owner[j], str(team.value)) and (not re.findall('Defense', str(position.value)))
If you want alternatives in a regex, use | in the pattern:
re.match(owner[j], str(team.value)) and (not re.findall('Defense|K,|KFG|KKO', str(position.value)))

Format mask for number field items: trailing and 'leading' zero

I'm having some trouble with displaying numbers in apex, but only when i fill them in through code. When numbers are fetched through an automated row fetch, they're fine!
Leading Zero
For example, i have a report where a user can click a link, which runs a javascript function. There i get detailed values for that record through an application process. The returned values are in JSON. Several fields are number fields.
My response looks as follows (fe):
{"AVAILABLE_STOCK": "15818", "WEIGHT": ".001", "VOLUME": ".00009", "BASIC_PRICE": ".06", "COST_PRICE": ".01"}
Already the numbers here 'not correct': values less than one do not have a zero before the .
I kind of hoped that the format mask on the items would catch this. If i specify FM999G990D000 for the item weight, i'd expect it to show '0.001' .
But okay, i suppose it only works that way when it comes through session state, and not when you set an item value through $("#").val() ?
Where do i go wrong? Is my only option to change my select in the app process?
Now:
SELECT '"AVAILABLE_STOCK": "' || AVAILABLE_STOCK ||'", '||
'"WEIGHT": "' || WEIGHT ||'", '||
'"VOLUME": "' || VOLUME ||'", '||
'"BASIC_PRICE": "' || BASIC_PRICE ||'", '||
Do i need to provide my numberfields a to_char with the format mask here (to_char(available_stock, 'FM999G990D000')) ?
Right now i need to put my numbers between quotes ofcourse, or i get invalid json when i parse it.
Trailing Zero
I have an application process on a page on the after header point, right after an automated row fetch. Several fields are calculated here (totals). The variables used are all specified as number(10, 2). All values are correct and rounded to 2 values after the comma. My format masks on the items are also specified as FM999G999G990D00.
However, when one of the calculated values has only one meaningfull value after the comma, the trailing zeros get dropped. Instead of '987.50', it is displayed as '987.5'.
So, i have a number variable, and assign it like this: :P12_NDB_TOTAL_INCL := v_totI;
Would i need to convert my numbers here too, with format mask?
What am i doing wrong, or what am i missing?
If you aren't doing math on it and are more concerned with formatting, I suggest treating it as a varchar/string instead of as a number wherever you can.