2016-06-28 64 views
2

我正在使用passport-bnet來驗證使用battlenet的用戶(他們可以有多個服務)。我有如下的格式用戶對象:根據JSON中的值插入表格

{ 
    "id": 1, 
    "name": "Meow", 
    "battlenet": { 
    "id": 5, 
    "tag": "obviously-not-a-real-battletag#1234" 
    } 
} 

當我驗證用戶,我給出的響應交戰用戶的ID。我試圖做的是從這個JSON字段中選擇ID並創建它,如果它不存在。

passport.use(new Battlenet({/**...*/}, function (accessToken, refreshToken, profile, done) { 
    database 
    .select('*') 
    .where('battlenet->id', '=', profile.id) 
    .then(user => done(null, user)) 
    .catch(done); 
}); 

但是,我有點麻煩。如何插入此用戶文檔以包含一些默認值?從本質上講,我想在蒙戈

{ 
    $setOnInsert: { name: profile.tag.replace(/\W/, '') }, 
    $set: { battlenet: profile } 
} 

這將如何通過knex和Postgres做類似這種修改的東西嗎?

回答

0

我有點難以理解你的模式以及你想在什麼時候發生什麼,相同的查詢會運行兩次。隨時更新問題,我可能會給出更完整的答案。

一般爲knex出現了約UPSERT討論

https://github.com/tgriesser/knex/issues/54https://github.com/tgriesser/knex/issues/1121

討論得出的結論是一個還是應該使用原始的SQL(knex.raw)FR UPSERT。

對於問題的SQL部分,我相信關鍵是您需要爲battlenet->id屬性創建UNIQUE約束。之後,可以做INSERT s,它與JSONB屬性中的重複id相沖突。

事情是這樣的:

CREATE UNIQUE INDEX t_id ON t((json->>'id')); 

,它應該很容易UPSERT寫這實際上更新後,只是一些JSONB與jsonb_set功能的幫助下屬性。