Total Pageviews

2018/06/15

[Neo4j] Cypher Example

在 graph database 中,擁有以下 User 與 Movie 的關係:





以下有數個查詢的例子:
// 找出 John Johnson 與其朋友共同看過的電影
match (u:User)-[:IS_FRIEND_OF]->()-[:HAS_SEEN]->(m:Movie)
where u.name="John Johnson" and not((u)-[:HAS_SEEN]->(m))
return m as movie;




// 找出 John Johnson 的朋友看過的,但是 John Johnson 沒看過的電影
match (u:User)-[:IS_FRIEND_OF]->()-[:HAS_SEEN]->(m:Movie)
where u.name="John Johnson" and (u)-[:HAS_SEEN]->(m)
return m as movie;





// 找出大家看過的電影,剔除重複的電影
match (u:User)-[:HAS_SEEN]->(m:Movie)
return distinct m as movie





// 找出 yearOfBirth 比 John Johnson 大的朋友
match (u1:User)-[:IS_FRIEND_OF]-(friend:User)
where u1.name="John Johnson" and  friend.yearOfBirth > u1.yearOfBirth
return friend




// 找出 John Johnson 的朋友中,使用 gmail mailbox 的人
match (u1:User)-[:IS_FRIEND_OF]-(friend:User)
where u1.name="John Johnson" and friend.email =~ ".*@gmail.com"
return friend




// 找出每個人有幾個朋友 (數量以降冪排序)
match (u:User)-[:IS_FRIEND_OF]-()
return u as user, count(*) 
order by count(*) desc




// 找出 John Johnson 與其他節點的關係,並統計數量
match (u:User)-[rel]-()
where u.name="John Johnson"
with u.name as name, type(rel) as rel, count(*) as count
return name, rel, count



2018/06/14

[Neo4j] Importing data using spreadsheets

假設我想要在 neo4j 建立起下圖的關係


分析與執行步驟如下:



由關係圖可以看出會有七個節點,包含
  • 哆啦A夢
  • 大雄
  • 靜香
  • 小夫
  • 胖虎
  • 小叮鈴
  • 玉子 (大雄的媽媽)
  • 伸助 (大雄的爸爸)

這七個人,就分別是 graph database 中的七個節點,分別給予 id 與 label ,Excel 內容如下:


這七個人 (nodes) 之間的有九個關係:
  • 大雄的寵物是哆啦A夢
  • 大雄的配偶是靜香
  • 大雄的朋友是小夫
  • 大雄的朋友是胖虎
  • 小夫的朋友是胖虎
  • 哆啦A夢的妹妹是小叮鈴
  • 大雄的爸爸是伸助
  • 大雄的媽媽是玉子
  • 伸助的配偶是玉子

在 Excel 中,關係表示如下:


透過 Excel 內建的 CONCATENATE 語法,產生 create nodes / relationship 的 Cypher 語法
建立 nodes 的 Excel formula:
=CONCATENATE("create(n",A2, ":", ,C2, " {id:", A2, ", name:'",B2, "'}", ")")

建立 relationships 的 Excel formula:
=CONCATENATE("create(n",E2,")-[:",G2,"]->(n",H2,")")
依據上述 nodes 與 relationship ,產生的 Cypher 語法如下:

create(n1:男生 {id:1, name:'哆啦A夢'})
create(n2:男生 {id:2, name:'大雄'})
create(n3:女生 {id:3, name:'靜香'})
create(n4:男生 {id:4, name:'小夫'})
create(n5:男生 {id:5, name:'胖虎'})
create(n6:女生 {id:6, name:'小叮鈴'})
create(n7:女生 {id:7, name:'玉子'})
create(n8:男生 {id:8, name:'伸助'})

create(n2)-[:PET_OF]->(n1)
create(n2)-[:SPOUSE_OF]->(n3)
create(n2)-[:FRIEND_OF]->(n4)
create(n2)-[:FRIEND_OF]->(n5)
create(n4)-[:FRIEND_OF]->(n5)
create(n1)-[:SISTER_OF]->(n6)
create(n2)-[:MOTHER_OF]->(n7)
create(n2)-[:FATHER_OF]->(n8)
create(n8)-[:SPOUSE_OF]->(n7)

將上述語法貼到 Neo4j Browser 並執行


產生的 graph 如下:



2018/06/13

[PostgreSQL] How to update data from a sub-query

Problem
I have two tables, project and intent, in my database.


I import data into intent table, but found out I mistype some data in intent.value column. All data in intent.value should start with qa_.

How to iron out this problem using update statement?

How-To
Here has an example to fix this problem:
1
2
3
4
5
6
7
8
9
  update intent
  set value = source.new_value
  from(
      select id as intent_id, value, 'qa_' || value as new_value, project_id as proj_id
      from intent 
      where project_id= (select id from project where identifier='test')
      and substring(value, 1, 3) <> 'qa_' 
  ) as source
  where id = source.intent_id and project_id = source.proj_id


2018/06/12

[jackson] How to define ordering when serializing object properties to JSON ?

Problem
How to define ordering when serializing object properties to JSON ?
Employ class
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  package test.albert.jackson;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  public class Employee {
  
      private Integer id;
  
      private String name;
  
      private String email;
  
      private String phone;
  
      private Address address;
  
  }


Address class
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  package test.albert.jackson;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  public class Address {
  
      private String streetAddress;
      private String city;
      private String zipCode;
  
  }


Using ObjectMapper to serialize object properties to JSON
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  package test.albert.jackson;
  
  import java.io.IOException;
  
  import com.fasterxml.jackson.databind.ObjectMapper;
  
  import lombok.extern.slf4j.Slf4j;
  
  @Slf4j
  public class JacksonTest {
  
      public static void main(String[] args) throws IOException {
          Address address = Address.builder().zipCode("110").city("台北市").streetAddress("信義區信義路五段7號").build();
          Employee albert = Employee.builder().id(1).name("Albert").email("albert@gmail.com").phone("0900123456")
                  .address(address).build();
          
          ObjectMapper mapper = new ObjectMapper();
          
          // convert object to JSON
          String json = mapper.writeValueAsString(albert);
          log.debug(json);
      }
  
  }


How-to
You can make good use of @JsonPropertyOrder to define the ordering, for example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  package test.albert.jackson;
  
  import com.fasterxml.jackson.annotation.JsonPropertyOrder;
  
  import lombok.Builder;
  import lombok.Data;
  
  @Data
  @Builder
  @JsonPropertyOrder({ "id", "name", "address", "phone", "email" })
  public class Employee {
  
      private Integer id;
  
      private String name;
  
      private String email;
  
      private String phone;
  
      private Address address;
  
  }


2018/06/11

[JavaScript] How to get selected value from a drop-down list that allows multiple selections ?

Problem
Assume I have a drop-down list that allows multiple selections.
1
2
3
4
5
6
7
   <select class="form-control" multiple id="importIntentList" 
           name="importIntentList" style="height: 100%;" size="20">
      <option value="1">A</option>
      <option value="2">B</option>
      <option value="3">C</option>
      <option value="4">D</option>
   </select>

I try to get selected value from the drop-down list, how to do it?


How-To
Here has code snippet to get values from the multi-selected drop-down list and push values into array:
1
2
3
4
5
6
7
   var intentSelectedOptions = [];
   var items = document.getElementById("importIntentList");
   for (var i = 0; i < items.options.length; i++) {
       if (items.options[i].selected == true) {
           intentSelectedOptions.push(items.options[i].value);
       }
   }


2018/06/10

[Bootbox] How to keep the modal dialog open until the input is valid?

Problem
I utilize Bootbox to open a dialog, it has one dropdown list for end user to select. And click Import button after select dropdown list.



The code snippet looks like:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
bootbox.dialog({
    title: '匯入專案',
    buttons: {
        importProject: {
            label: '匯入',
            className: 'btn-primary',
            callback: function() {
                var projectSelectedVal = document.getElementById("projectList").value;
                var importOptionVal = document.querySelector('input[name="importOption"]:checked').value;
                if (projectSelectedVal == '') {
                    bootbox.alert('<font color=red><b>請選擇要匯入的專案</b></font>');
                } else {
                    // do something
                }
            }
        },
        cancel: {
            label: '取消'
        }
    }
});

If end user do not select required attribute, I will show warning message to end user. But the Bootbox dialog will close it automatically, how do I keep the dialog open?


How-to
Here has updated code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
bootbox.dialog({
    title: '匯入專案',
    buttons: {
        importProject: {
            label: '匯入',
            className: 'btn-primary',
            callback: function() {
                var projectSelectedVal = document.getElementById("projectList").value;
                var importOptionVal = document.querySelector('input[name="importOption"]:checked').value;
                if (projectSelectedVal == '') {
                    bootbox.alert('<font color=red><b>請選擇要匯入的專案</b></font>');
                    return false;
                } else {
                    // do something
                }
            }
        },
        cancel: {
            label: '取消'
        }
    }
});



2018/06/09

[liquibase] How to add new column in YAML?

Problem
I attempt to add new column in existing table, how to define these change in YAML?


How-To
YAML will looks like:
  - changeSet:
      id: 4
      author: albert
      changes:     
       - addColumn:
          tableName: model_sentence
          columns:  
          - column:
             name: is_green_icon
             type: int


Reference
[1] http://www.liquibase.org/documentation/changes/add_column.html

2018/06/08

[liquibase] How to rename column and modify data type in YAML?

Problem
I attempt to rename an existing column name and modify its data type in liquibase, how to define these changes in YAML?


How-To
YAML will looks like:
  - changeSet:
      id: 4
      author: albert
      changes:     
       - renameColumn:
          tableName: model
          oldColumnName: PREDICT_JSON
          newColumnName: STATISTICS_JSON        
       - modifyDataType:
          tableName: model
          columnName: STATISTICS_JSON
          newDataType: text


Reference
[1] http://www.liquibase.org/documentation/changes/rename_column.html
[2] http://www.liquibase.org/documentation/changes/modify_data_type.html

2018/06/07

[Tools] How to format JSON string in Notepad++

Problem
How to format JSON string in Notepad++?

How-To
You can download JSONViewer Notepad++ plugin, https://sourceforge.net/projects/nppjsonviewer/?source=typ_redirect to fulfill your requirement.

The process regarding download and configuration is as bellows:


You can select all text and use Plugins -> JSON Viewer -> Format JSON to do JSON format



2018/06/06

[Git] How to resolve non-fast-forward problem?

Problem
As I try to push my branch to GitLab
git push origin fix_issue6


I get this error message when I do push:
To https://gitlab.com/xxx/xxx.git
 ! [rejected]        fix_issue6 -> fix_issue6 (non-fast-forward)
error: failed to push some refs to 'https://gitlab.com/xxx/xxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.



How-To
Here has the resolution process:

2018/06/05

[閱讀筆記] Antifragile: Things That Gain from Disorder (1/10)


  1. 反脆弱的基本定義,”因為變動,造成的傷害小於帶來的獲益,那就是反脆弱”。
  2. 人類的免疫機制為我們提供了一個認識反脆弱的視角——反脆弱性能讓你從適當的「壞事」中獲益,讓你從脆弱邁向強韌,而強韌則能讓你抵抗更多不利的環境因素。不過要特別注意的是,「壞事」是有分大小的,小壞事無法起到成長的作用,而太大的壞事你可能無法承受。了解了這些之後你會發現,當我們在評估一個人是否強大時,不應該只考慮他現在有多強韌,也應該同時考慮他的反脆弱性,因為具備反脆弱性才能讓他跟上環境的腳步,持續的變得越來越強。
  3. 以人為例,如果你每次染上小病都立刻服用抗生素,那你就喪失了一次「鍛煉」免疫系統的機會,更糟的是,你體內的病菌可能會因你長期服用抗生素而出現抗體,變得更頑強,換言之,你變得更脆弱。塔雷伯把遇上小病就立刻服用抗生素的行為稱為「過度干預」,而醫生成了「脆弱推手」,因為是醫生讓你吃抗生素的,是他間接的把你推向脆弱的。
  4. 當環境發生變化時,容易遭受損害代表「脆弱」(fragile);不受影響代表「強固」(robust);變得更大更強則是「反脆弱」(antifragile)。
  5. 未來是個急遽變化的時代,與其對抗改變,不如加強自己的「反脆弱性」,轉身擁抱改變!
  6. 讓黑天鵝的出現變成對自己有利,能從黑天鵝事件中得到好處,這就是「反脆弱」(antifragile)
  7. 有個簡單的測試可以判斷是脆弱(fragile)或是反脆弱(antifragile),若可以從隨機事件(random events)中獲得有利多於不利就是反脆弱(antifragile),反之就是脆弱(fragile)
  8. 無論是在商場、政治、醫療或是人生,充滿著在不確定的狀況下進行不可預測的(unpredictive decision)決策制定,這些狀況都是隨機的、無法預測的、不透明的或不全然了解的
  9. 人類很本能的想要抑制隨機(randomness)與不穩定(volatility),如此作法會讓人類脆弱化,舉凡經濟、健康、政治、教育等等領域,無所不在
  10. 人類通常會將過去的歷史轉化成平順的、線性與能自圓其說的事件,讓我們低估了隨機性
  11. 複雜系統充滿了難以察覺的相互依賴與非線性的反應。非線性(nonlinear)表示,你施打兩倍的藥物劑量,或指派兩倍的員工數量到產線,你未必可以得到兩倍的效果,有時候可能得到多一點點的效果,或者是比原本更少的效果
  12. Black Swan Problem (黑天鵝問題)最惱人的地方是,罕見事件發生機率是無法計算的。我們對於百年一遇的洪水的了解,一定比五年一遇的洪水了解來得少。
  13. 越罕見的事件,我們就越少去做追蹤,我們就越無法知道其發生頻率,也越無法預期發生後產生的後果
  14. 人類常有求取安逸與穩定的傾向,懂得反脆弱現象,就會知道追求安定,其實是追求脆弱的人生。
  15. 系統就是要經歷挑戰、變化、波動、不安,它才會更好。安逸與穩定,反而會讓它失去進步的契機。
  16. 反脆弱(antifragile)可能可以提供對黑天鵝事件的一些基本防護力。因為黑天鵝就定義來說,就是事前不知道,無法預期,有嚴重影響的重大事件。脆弱的系統將被黑天鵝毀滅,但反脆弱的系統有機會走過黑天鵝的挑戰。
  17. 反脆弱(antifragile)是解決 Black Swan Problem (黑天鵝問題)的解藥,並且了解反脆弱(antifragile)會讓你理解這些罕見事件在人類發展的歷史、科技、知識等任何事物,都是會發生的
  18. 脆弱 (fragile) 是可衡量的,風險則未必,特別是與罕見事件相關的風險
  19. 我們可以衡量脆弱與反脆弱,但是我們無法計算風險與罕見事件的發生機率。例如我們可以評估新建的大樓與 40 年的老公寓,若遇到大地震,後者會比較脆弱;又如當氣溫發生劇烈變化,你的外婆的身體反應會比你更強烈
  20. 大自然具有反脆弱性。生命會消亡,但基因密碼會留下來,大自然藉著不斷淘汰脆弱的事物,來達成整個系統的反脆弱性。持續不斷的失敗,有助於保存整個系統。少了波動,就沒有穩定。
  21. 脆弱推手(fragilista)容易產生由上而下的政策和古怪的新發明,還誤把未知當作不存在。醫療脆弱推手總是過度干預,忽視人體自然的痊癒能力,而開出可能有非常嚴重副作用的藥,連醫生自己都不敢吃;政策脆弱推手誤把經濟當作洗衣機,認為需要三不五時由他不斷出手去攪和;精神脆弱推手用藥物治療孩子,讓他們在教室裡更安份;金融脆弱推手推出風險模型,摧毀了銀行體系,然後卻又再度使用它們
  22. 我們應該用否定法來解決問題,消除錯誤的知識。否定法的應用是建立在少即是多的觀念上,把有限的資源投注在掃除風險。他認為,對於創新與發明,不需要理論的指導,嘗試錯誤的貢獻遠大於正規科學
  23. 引發 2008 年的金融危機,就是由於現代法律、經濟和政治事務日趨複雜,偷偷讓別人承受風險而爆炸的這種做法很容易掩飾。美國立個法,隨便都是幾千頁。愈繁複的法規,就愈能讓參與立法者鑽漏洞
  24. 「因為每個人都這麼做」並不會使事情變成正確,但大家卻經常誤解。社會執行似乎沒有道理的活動行之有年,而且因為未知的理由而繼續堅持做下去
  25. 這個世界的魅力,在於我們沒有能力真正了解它
  26. 『沒有作為』不被認為是種行動,因此我們繼續對於雜訊過度反應,而且這也是為什麼「專業經理人」基金的表現通常很差
  27. 越複雜的系統,越不透明,若再加上人為干涉,會導致無法預期的後果。The simpler, the better
  28. 不要將系統複雜化,秉持著少即是多的觀念,而且通常更有效率
  29. 我們沒有能力預知未來可能有哪些波動 (volatility),我們應聚焦於當波動發生時該如何反應
  30. 我們身處高度不確定、隨機、無法計算機率、非線性與失序的世界,我們常在資訊不透明、複雜與隨機的狀況下進行決策制定