I would like to check in KQL (Kusto Query Language) if a string starts with any prefix that is contained in a list.
Something like:
let MaxAge = ago(30d);
let prefix_list = pack_array(
'Mr',
'Ms',
'Mister',
'Miss'
);
| where Name startswith(prefix_list)
I know this example can be done with startswith("Mr","Ms","Mister","Miss") but this is not escalable.
an inefficient but functional option would be using matches regex - this can work well if the input data set is not too large:
let T = datatable(Name:string)
[
"hello" ,'world', "Mra", "Ms 2", "Miz", 'Missed'
]
;
let prefix_list = pack_array(
'Mr',
'Ms',
'Mister',
'Miss'
);
let prefix_regex = strcat("^(", strcat_array(prefix_list, ")|("), ")");
T
| where Name matches regex prefix_regex
Name
Mra
Ms 2
Missed
This function is not available in the Kusto query language, you are welcome to open a suggestion for it in the user feedback form
Related
Kusto Query Language provides IndexOf function (searches the first occurrence). The question is how to find the last occurrence of some substring.
I guess, the best you can do is (example on how to search for last "cde" in "abcdefabcdef"):
datatable (name:string, lookup:string)["abcdefabcdef", "cde"]
| project value = strlen(name) - indexof(reverse(name), reverse(lookup)) - strlen(lookup)
You can pass the result of countof to the occurence parameter of indexof:
let lastIndexof = (input:string, lookup: string) {
indexof(input, lookup, 0, -1, countof(input,lookup))
};
print lastIndexof("abcdefabcdef", "cde")
I have a search request written as
import sqlite3
conn = sqlite3.connect('locker_data.db')
c = conn.cursor()
def search1(teacher):
test = 'SELECT Name FROM locker_data WHERE Name or Email LIKE "%{0}%"'.format(teacher)
data1 = c.execute(test)
return data1
def display1(data1):
Display1 = []
for Name in data1:
temp1 = str(Name[0])
Display1.append("Name: {0}".format(temp1))
return Display1
def locker_searcher(teacher):
data = display1(search1(teacher))
return data
This allows me to search for the row containing "Mr FishyPower (Mr Swag)" or "Mr FishyPower / Mr Swag" with a search input of "FishyPower". However, when I try searching with an input of "Swag", I am then unable to find the same row.
In the search below, it should have given me the same search results.
The database is just a simple 1x1 sqlite3 database containing 'FishyPower / Mr Swag'
Search Error on 'Swag'
Edit: I technically did solve it by limiting the columns being searched to only 'Name' but I intended the code search both the 'Name' and 'Email' columns and output the results as long as the search in within either or both columns.
Edit2: SELECT Name FROM locker_data WHERE Email LIKE "%{0}%" or Name LIKE "%{0}%" was the right way to go.
I'm gonna guess that Mr. FishyPower's email address is something like mrFishyPower#something.com. The query is only comparing Email to teacher. If it was
WHERE Name LIKE "%{0}%"
OR Email LIKE "%{0}%"'
you would (probably) get the result you want.
I need to search those elements who have space " " in their attributes.
For example:
<unit href="http:xxxx/unit/2 ">
Suppose above code have space in the last for href attribute.
I have done this using FLOWER query. But I need this to be done using CTS functions. Please suggest.
For FLOWER query I have tried this:
let $x := (
for $d in doc()
order by $d//id
return
for $attribute in data($d//#href)
return
if (fn:contains($attribute," ")) then
<td>{(concat( "id = " , $d//id) ,", data =", $attribute)}</td>
else ()
)
return <tr>{$x}</tr>
This is working fine.
For CTS I have tried
let $query :=
cts:element-attribute-value-query(xs:QName("methodology"),
xs:QName("href"),
xs:string(" "),
"wildcarded")
let $search := cts:search(doc(), $query)
return fn:count($search)
Your query is looking for " " to be the entirety of the value of the attribute. If you want to look for attributes that contain a space, then you need to use wildcards. However, since there is no indexing of whitespace except for exact value queries (which are by definition not wildcarded), you are not going to get a lot of index support for that query, so you'll need to run this as a filtered search (which you have in your code above) with a lot of false positives.
You may be better off creating a string range index on the attribute and doing value-match on that.
Context
In PeopleCode, the following declaration with MessageBox is valid:
MessageBox(0, "", 0, 0, "Something = %1, Something else = %2.", &something, &somethingElse);
This allows me to use bind variables for the MessageBox. The same is also true with SQL:
SQLExec("SELECT * FROM %Table(:1) WHERE VALUE = :2", Record.Y_SOMETHING, &value);
Question
Is there a way to do that with normal strings? I've never liked having to "pipe" strings together like this &string = Something = " | &something | ", Something else = " | &somethingElse | ".".
Is there a way to use this format for regular strings? I've looked through various of Oracle's PeopleBooks, but I haven't found anything.
Maybe this is what you are looking for:
Local number &message_set, &message_num;
Local string &default_msg_txt = "%1 %2 %3";
Local string &l_result= MsgGetText(&message_set, &message_num, &default_msg_txt, "hallo", "Frank", "!");
result:
"hallo Frank !"
You can use MsgGetText function to determine a message by message catalogue. In case the message is not found, the default text is used.
I am using cts:search like this:-
let $query :=
cts:or-query((
cts:field-word-query(
"Assignor Name", $assignorName
),
cts:field-word-query(
"Assignee Name", $assigneeName
)
))
for $patent in cts:search(fn:doc(), $query)[1 to 10]
return $patent
where $assignorName and $assigneeName is the input from the user. But when both $assignorName & $assigneeName are empty strings then it does not show any results. I want to show all the results when the user does not enter any input. How can I achieve this ?
More explicitly, you might write the query something like this:
cts:or-query((
if (not($assignorName)) then () else cts:field-word-query(
"Assignor Name", $assignorName),
if (not($assigneeName)) then () else cts:field-word-query(
"Assignee Name", $assigneeName) ))
It takes a while to get used to the idea that you can put an if-then-else expression practically anywhere. Sometimes it helps to think of it as ternary logic.
To get all results, you have to replace the current $query with cts:and-query(()). A cts:or-query(()) might work too by the way.
HTH!