Solr FunctionQuery: gte, lte, eq functions - solr

Solr FunctionQuery has a DIV(x,y) function. I have such a need if y=0, then y should be equal to x.
In other words, I need to represent the following logic with FunctionQuery:
if y == 0, return 1 /* i.e. DIV(x,x) */
else, return DIV(x,y)
Somehow, from the Solr doc, I cannot find any comparison function, e.g. EQ(x, value), etc. for me to use.
Will anyone be able to give me a hint to construct my desired logic using FunctionQuery?
Thanks!

To clean up this question and log what is my final solution, thanks to Srikanth Venugopalan comment:
actually you need to switch the arguments. exposure_count = 0 is interpreted as false. So your condition would be {!boost b=if(exposure_count,div(1,exposure_count),1)}"
As it seems, Lucid works documentation does have a mistake. The FunctionQuery parser does not take comparison operators such as ==, at least this is what I found by looking into the sourcecode. Also, the field separator for IF() function should be ,(comma) and not ;(semi-colon).
The official Solr wiki is correct.

For string terms this works:
if(termfreq(fieldname,"value"),2,1)
which yields 2 if "value" is contained in "fieldname" (termfreq will be >0)

you can use == for equals and if conditional statement as below :-
e.g. if(y == 0; 1; DIV(x,y))
Check for the example # Documentation
if(color=="red"; 100; if(color=="green"; 50; 25)) :
This function checks the document field "color", and if it is "red" returns 100, if it is "green" returns 50, else returns 25.
Edit :-
Solr if wiki mentions , (comma) as seperator
e.g. if(exists(myField),100,0)

Related

Converting Excel Formula involving *OR to TSQL

I'm trying to convert this formula into T-SQL.
=IF(D6>F6,D6-C6-1,F6-C6-1)*OR(IF(F6-C6-1<0,0,F6-C6-1))
Does anyone know what the *OR actually means?
The columns C, D, F are all Date fields.
For example
For the first line, this part of the formula IF(D6>F6,D6-C6-1,F6-C6-1) returns 35 and the second part of the formula IF(F6-C6-1<0,0,F6-C6-1) returns 35 as well. So shouldn't the result be 35 x 35 = 1225. The correct answer is 35 however.
As per my earlier comment:
The second parameter in the OR would be optional. As a matter of fact, or will just return 'TRUE' if any of it's paramaters is 'TRUE', no matter the amount of (optional) parameters you use. The 'OR' in this case just evaluates the outcome of the second 'IF' (which is 35). So > 'OR(35)' which evaluates to TRUE. Since you multiply this will again evaluate to '35*1' being your final result. The formula is looking strange because 'OR' would always return true in this case. The formula might as well just be '=IF(D6>F6,D6-C6-1,F6-C6-1)'

IF statement for last value in LookupSet expression

I have an expression to get the last date value but I get '#Error' if there is no date entered. (IF part returns #Error because no date has been entered - the Else part returns a date). Here is the expression:
IIF(LookupSet(Fields!Denial_ID.Value,Fields!Denial_ID.Value,Fields!Appeal_Date_Entered.Value,"DataSet2").Length() =0, "", LookupSet(Fields!Denial_ID.Value, Fields!Denial_ID.Value, Fields!Appeal_Date_Entered.Value, "DataSet2")(LookupSet(Fields!Denial_ID.Value, Fields!Denial_ID.Value, Fields!Appeal_Date_Entered.Value, "DataSet2").Length() -1))
I'm definitely not a report writer, but there's some strange stuff in your expression which make me expect it not to work. Below is a formatted version of it (it's easier to analyse it, although I have no idea of whitespace syntax in MRB):
IIF(
LookupSet(Fields!Denial_ID.Value,
Fields!Denial_ID.Value,
Fields!Appeal_Date_Entered.Value,"DataSet2").Length() =0,
"",
LookupSet(Fields!Denial_ID.Value,
Fields!Denial_ID.Value,
Fields!Appeal_Date_Entered.Value, "DataSet2")
(LookupSet(Fields!Denial_ID.Value,
Fields!Denial_ID.Value,
Fields!Appeal_Date_Entered.Value,
"DataSet2").Length() -1)
)
According to docs, the IIF syntax is the following:
=IIF(condition, valueIfTrue, valueIfFalse)
but your expression looks like this:
IIF(condition, valueIfTrue, valueIfFalse (someOtherStuff))
so you should describe what you expect to get from that expression and change it to accord the standart syntax (see also examples on the referenced page).

Postgres NOT in array

I'm using Postgres' native array type, and trying to find the records where the ID is not in the array recipient IDs.
I can find where they are IN:
SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))
But this doesn't work:
SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3 = NOT ANY (recipient_ids))
What's the right way to test for this condition?
SELECT COUNT(*) FROM "messages" WHERE NOT (3 = ANY (recipient_ids))
You can always negate WHERE (condition) with WHERE NOT (condition)
You could turn it around a bit and say "3 is not equal to all the IDs":
where 3 != all (recipient_ids)
From the fine manual:
9.21.4. ALL (array)
expression operator ALL (array expression)
The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator, which must yield a Boolean result. The result of ALL is "true" if all comparisons yield true (including the case where the array has zero elements). The result is "false" if any false result is found.
Beware of NULLs
Both ALL:
(some_value != ALL(some_array))
And ANY:
NOT (some_value = ANY(some_array))
Would work as long as some_array is not null. If the array might be null, then you must account for it with coalesce(), e.g.
(some_value != ALL(coalesce(some_array, array[]::int[])))
Or
NOT (some_value = ANY(coalesce(some_array, array[]::int[])))
From the docs:
If the array expression yields a null array, the result of ANY will be null
If the array expression yields a null array, the result of ALL will be null
Augmenting the ALL/ANY Answers
I prefer all solutions that use all or any to achieve the result, appreciating the additional notes (e.g. about NULLs). As another augementation, here is a way to think about those operators.
You can think about them as short-circuit operators:
all(array) goes through all the values in the array, comparing each to the reference value using the provided operator. As soon as a comparison yields false, the process ends with false, otherwise true. (Comparable to short-circuit logical and.)
any(array) goes through all the values in the array, comparing each to the reference value using the provided operator. As soon as a comparison yields true, the process ends with true, otherwise false. (Comparable to short-circuit logical or.)
This is why 3 <> any('{1,2,3}') does not yield the desired result: The process compares 3 with 1 for inequality, which is true, and immediately returns true. A single value in the array different from 3 is enough to make the entire condition true. The 3 in the last array position is prob. never used.
3 <> all('{1,2,3}') on the other hand makes sure all values are not equal 3. It will run through all comparisons that yield true up to an element that yields false (the last in this case), to return false as the overall result. This is what the OP wants.
an update:
as of postgres 9.3,
you can use NOT in tandem with the #> (contains operator) to achieve this as well.
IE.
SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids #> ARRAY[3];
not (3 = any(recipient_ids))?
Note that the ANY/ALL operators will not work with array indexes. If indexes are in mind:
SELECT COUNT(*) FROM "messages" WHERE 3 && recipient_ids
and the negative:
SELECT COUNT(*) FROM "messages" WHERE NOT (3 && recipient_ids)
An index can then be created like:
CREATE INDEX recipient_ids_idx on tableName USING GIN(recipient_ids)
Use the following query
select id from Example where NOT (id = ANY ('{1, 2}'))

SSIS How to get part of a string by separator

I need an SSIS expression to get the left part of a string before the separator, and then put the new string in a new column. I checked in derived column, it seems no such expressions. Substring could only return string part with fixed length.
For example, with separator string - :
Art-Reading Should return Art
Art-Writing Should return Art
Science-chemistry Should return Science
P.S.
I knew this could be done in MySQL with SUBSTRING_INDEX(), but I'm looking for an equivalent in SSIS, or at least in SQL Server
Better late than never, but I wanted to do this too and found this.
TOKEN(character_expression, delimiter_string, occurrence)
TOKEN("a little white dog"," ",2)
returns little the source is below
http://technet.microsoft.com/en-us/library/hh213216.aspx
of course you can:
just configure your derived columns like this:
Here is the expression to make your life easier:
SUBSTRING(name,1,FINDSTRING(name,"-",1) - 1)
FYI, the second "1" means to get the first occurrence of the string "-"
EDIT:
expression to deal with string without "-"
FINDSTRING(name,"-",1) != 0 ? (SUBSTRING(name,1,FINDSTRING(name,"-",1) - 1)) : name
You can specify the length to copy in the SUBSTRING function and check for the location of the dash using CHARINDEX
SELECT SUBSTRING(#sString, 1, CHARINDEX('-',#sString) - 1)
For the SSIS expression it is pretty much the same code:
SUBSTRING(#[User::String], 1, FINDSTRING(#[User::String], "-", 1)-1)
if SUBSTRING length param returns -1 then it results in error,
"The length -1 is not valid for function "SUBSTRING". The length parameter cannot be negative. Change the length parameter to zero or a positive value."

Is SQL Server's double checking needed here?

IF #insertedValue IS NOT NULL AND #insertedValue > 0
This logic is in a trigger.
The value comes from a deleted or inserted row (doesn't matter).
2 questions :
Do I need to check both conditions? (I want all value > 0, value in db can be nullable)
Does SQL Server check the expression in the order I wrote it ?
1) Actually, no, since if the #insertedValue is NULL, the expression #insertedValue > 0 will evaulate to false. (Actually, as Martin Smith points out in his comment, it will evaluate to a special value "unknown", which when forced to a Boolean result on its own collapses to false - examples: unknown AND true = unknown which is forced to false, unknown OR true = true.) But you're relying on comparison behaviour with NULL values. A single step equivalent method, BTW, would be:
IF ISNULL(#insertedValue, 0) > 0
IMHO, you're better sticking with the explicit NULL check for clarity if nothing else.
2) Since the query will be optimised before execution, there is absolutely no guarantee of order of execution or short circuiting of the AND operator.
Combining the two - if the double check is truly unnecessary, then it will probably be optimised out before execution anyway, but your SQL code will be more maintainable in my view if you make this explicit.
You can use COALESCE => Returns the first nonnull expression among its arguments.
Now you can make the query more flexible, by increasing the column limits and again you need to check the Greater Then Zero condition. Important point to note down here is you have the option to check values in multiple columns.
declare #val int
set #val = COALESCE( null, 1, 10 )
if(#val>0)
select 'fine'
else
select 'not fine'

Resources