How to simplify neo4j query with multiple CASE's - database

We use the following cypher query in our project (just the relevant part, there's a bunch of MATCH and WHERE before this):
"RETURN entry.id AS id,\n" +
...
" CASE WHEN ljCase1 IS NOT NULL THEN {id: ljCase1.id, guide: false} \n" +
" ELSE CASE WHEN ljCase2 IS NOT NULL THEN {id: ljCase2.id, guide: true}\n" +
" ELSE CASE WHEN ljCase3 IS NOT NULL THEN {id: ljCase3.id, guide: true} END\n" +
" END\n" +
" END AS learningJourney\n" +
...
It works properly but I feel like this isn't done as clean as it could be.
Is there a way to simplify this part of the query?

perhaps something along the line of this, using COALESCE to avoid the nested CASE
WITH COALESCE(ljCase1,ljCase2,ljCase3) AS myCase
WITH CASE myCase
WHEN x THEN ..
WHEN y THEN ..
ELSE ..
END

Related

How to split pascal case address in SnowFlake?

In order to create PlaceKey for addresses to link some of my tables, I need to split an address column in SnowFlake.
I am not familiar with JavaScript, but I tried Javascript UDF in SnowFlake. Then I don't know how to deal with the addresses like '123_45ThSt'.
The output of my function is like '123_45 Th St'. I am stuck here.
The expected output is '123 45Th St'.
Hope someone could help me out. Much appreciated!
Below is another example and my SnowFlake SQL code:
Original address column: 12345NE17ThSt
The expected column: 12345 NE 17Th St
My function's output: 12345 NE17 ST
My function:
CREATE OR REPLACE FUNCTION Split_On_Upper_Case(s string)
RETURNS string
LANGUAGE JAVASCRIPT
AS '
function Split_On_Upper_Case(str){
str=str.split(/(?=[A-Z])/).join(" ")
return str
}
// Now call the function
return Split_On_Upper_Case(S);
'
;
Assuming the format of street address, which includes number + word (ends with lower case or number) + word (start with upper case), I have below solution:
CREATE OR REPLACE FUNCTION Split_On_Upper_Case(s string)
RETURNS string
LANGUAGE JAVASCRIPT
AS $$
regexp = /([0-9]+)(NE|SE|NW|SW)?(.*[0-9a-z]{1})([A-Z][a-zA-Z0-9]+)/g;
splits = regexp.exec(S.replace(/_/g, " "));
if (splits && splits.length == 5) {
return
splits[1].trim() + " " +
(splits[2] ? splits[2].trim() + " ": "" ) +
splits[3].trim() + " " +
splits[4].trim();
}
return "not found" // or whatever you want to do
$$;
Then try to run the function:
select Split_On_Upper_Case('12345NE17ThSt');
-- 12345 NE 17Th St
select Split_On_Upper_Case('123_45ThSt');
-- 123 45Th St
select Split_On_Upper_Case('35TestSt');
-- 35 Test St
It returns expected output, but if you have more sample inputs, they can help to validate.

NEO4J MERGE is not working as expected

I am new in neo4j and I am having problems with the MERGE clause. I have a method to do queries like this:
def upsert (idValue, valueField1):
query = "MERGE (n:Node {id: '" + idValue+ "'}) "
query += "ON MATCH SET n.field1= n.field1+ " + str(valueField1) + " "
query += "ON CREATE SET n = {id: '" + idValue + "', field1: 0} "
return db.run(query)
Then, I am calling the method like this:
upsert("1", 0)
upsert("2", 0)
upsert("3", 5)
upsert("1", 2)
upsert("1", 1)
So, afterthat, I expected this:
node (id="1", field1=3)
node (id="2", field1=0)
node (id="3", field1=0)
But, I am getting this:
node (id="1", field1=2)
node (id="2", field1=0)
node (id="3", field1=0)
In addition, If I do the same calls again, I got this:
node (id="1", field1=4)
node (id="2", field1=0)
node (id="3", field1=5)
Could anyone explain me what is happening and what am I doing wrong please? I was looking for on internet, but I couldn't find anything helpful for me.
With this query, that is exactly the same as what you are doing, I have the good result :
WITH [
{idValue:'1', valueField1:0},
{idValue:'2', valueField1:0},
{idValue:'3', valueField1:5},
{idValue:'1', valueField1:2},
{idValue:'1', valueField1:1}
] AS data
UNWIND data AS item
MERGE (n:Node {id:item.idValue})
ON MATCH SET n.field1= n.field1 + item.valueField1
ON CREATE SET n = {id:item.idValue, field1: 0}
And then with MATCH (n:Node) RETURN n.id, n.field1 ORDER BY n.id LIMIT 25 :
n.id n.field1
"1" 3
"2" 0
"3" 0
So I don't think that the problem comes from the query itself, but from its construction.
You should consider to use a parameterized query. It will be easier to read the query, but also code it and it's more performant in Neo4j.
So your code should be :
def upsert (idValue, valueField1):
query = "MERGE (n:Node {id:$id}) "
" ON MATCH SET n.field1= n.field1 + $value"
" ON CREATE SET n = {id:$id, field1: 0}"
return db.run(query, id=idValue, value=valueField1)

i want to Getting JSON values in python

Sorry. I can not explain the details because I am not fluent in English.
I have a json document like this:
[
{
"id":"96103252",
"pvname":"Bet365",
}
]
My python code looks like this:
url_odds= cfg.oddsurl
oddsfeed = urllib2.urlopen(url_odds)
oddsjson = json.load(oddsfeed)
getjson = "{""data"":" + oddsjson + "}"
for sport in getjson["data"]:
pv_id= validate(sport,"id")
pv_name= validate(sport,"pv_name")
sql= "INSERT INTO odds_sports(pv_id,pv_name) VALUES ('"
sql= sql+ pv_id + "','"
sql= sql+ pv_name + "')"
cursor.execute(sql)
conn.commit()
It sends this error
getjson = "{""data"":" + oddsjson + "}"
TypeError: cannot concatenate 'str' and 'list' objects
that's a very simple syntax error. in this line:
getjson = "{""data"":" + oddsjson + "}"
oddsjson is an array of dicts, you probably want to iterate over each element in it and parse the right value hence:
for sport in oddsjson:
pv_id = validate(sport.get("id"))
pv_name = validate(sport.get("pvname"))
also,
and on another issue. hand-writing SQL queries with strings you generate on the go is an invitation for troubles (especially when the query involves dynamic string generated by others).
you better use some library like sqlalchemy as a middleware to your database.

T-SQL Concatenating

I need to concatenate the following statement in SQL.
I am joining 2 tables, the MEDINFO table and the IMMUNIZE table.
There should be one record for each of the shot code dates as long as it is not null or 01/01/1901.
The output must look like this:
"Admin-" + medinfo_field_31 + ", Manuf-" + medinfo_field_32 + ", Lot-" + medinfo_field_33 + ", Exp-" + medinfo_field_34 + ", Site-" + medifno_field_35 + ", Dose-" + medinfo_field_36
Here is the criteria for the SQL statement I must create:
IF immunize_shot_code = 'FLU',
then concatenate medinfo_field_12 and medinfo_field_19 thru medinfo_field_24
IF immunize_shot_code = 'MENI',
then concatenate medinof_field_11 and medinfo_field_25 thru medinof_field_30
IF immunize_shot_code = 'TETA',
then concatenate medinfo_field_13 thru medinfo_field_18 and medinfo_field_31 thru medinfo_field_36"
Thanks for any ideas.
This would look something like the followning:
SELECT
(CASE WHEN Immunize_shot_code='Flu'
THEN medinfo_field_12+', '+med_info_field_19+ ', '+med_info_field_20+', '+med_info_field_21+ ', '+med_info_field_22+', '+med_info_field_23+', 'med_info_field_24
WHEN immunize_shot_code='MENI'
THEN [CONCATINATE AS PER ABOVE]
.....
.....
END) as ImmuCode
FROM TABLE_1
Like some of them mentioned above, you could use CASE statement something like this:
select
case when i.immunize_shot_Code = 'FLU'
then concat(m.medinfo_field_12,',',m.medinfo_field_19,',',m.medinfo_field_24...)
when i.immunize_Shot_Code = 'MENI'
then concat(m.medinfo_field_11,',',m.medinfo_field_11)
when i.immunize_Shot_code = 'TETA'
then concat(m.medinfo_field_13,',',m.medinfo_field18,',')
end as concat_value
from medinfo m
join immunize i on m.id = i.medinfo_id --change this to match your join
where (shot_code_date is not null or shot_code_date <> '01-01-1901');

Multiple tag search engine

Whenever we use hashtag for searching that always results from a single tag (except Tumblr).
Just wondering is there a search engine allows multiple tag search?
I suppose that using different combination of tags could be fun and accurate:
#A general results
#A, #B more specific
#A, #B, #C, #D close to the truth what attributes (tags) are given.
Is any website served in this way?
Or how can I build a database to make this happened?
Thank you a lot.
This is old and written in VB but the principle I think will work for you.
This code is not completely limiting to Images that have all of the tags it is instead pushing the images with the most tag hits to the top.
This code works from the idea of show the user what fits best first but then give them other options below. Where as your AND scenario would cut out something that worked for 4 out of 5 of the tags. In this scenario they would just show below tags that had 5 out of 5.
So if you had some images with tags like:
Given:
Image1 woman,dog,panda
Image2 woman,telephone,smiling
Image3 man,dog,panda,banana
Image4 man,telephone,smiling
Yield:
A tag search of "telephone smiling" would score [Image2] and [Image4] to the top of the listing.
A tag search of "panda" would only yield Image1 and Image3.
A tag search of "man dog panda banana" Would yield Image3 as the top followed by Image1 followed by Image4.
This implementation is for finding the best image based on tags.
You create 3 tables in your SQL database as such (if you are doing webpages or stories or whatever change image to that for your own clarity):
SQL Tables:
imageTag [INT ID, String Tag]
imageImages [INT ID, NVARCHAR(2000) Path]
imageConnections [INT TagID, INT ImageID]
VB.NET Code:
'The beef of the SQL statement to get the scored results is here.
Dim SearchString As String =
"SELECT it.path, count(it.path) AS cnt, it.Id, it.name, it.description, it.updated FROM imageimages AS it, imageconnections AS itt, imagetags AS t WHERE " + _
"{REPLACE-TAG} AND t.id = itt.tagid AND it.id = itt.imageid " + _
"GROUP BY Path, it.ID, it.name, it.description, it.updated ORDER BY cnt DESC"
Dim keywords As String() = tstSearch.Text.Split(New String() {" "}, StringSplitOptions.RemoveEmptyEntries)
If keywords.Length > 0 Then
Dim strReplacement As String
strReplacement = "( tag = '" + keywords(0) + "'"
If keywords.Length > 1 Then
For i As Integer = 1 To keywords.Length - 1
strReplacement += " OR tag = '" + keywords(i) + "'"
Next
End If
strReplacement += " )"
SearchString = SearchString.Replace("{REPLACE-TAG}", strReplacement)
dt = tran.GetDataTable(SearchString)
End If

Resources