2017-09-23 134 views
0

形式這個問題已經被問了幾次,但我一直無法找到一個解決方案:流星集合:UPSERT W /陣列

我有這樣一個模式(簡體):

StatusObject = new SimpleSchema({ 
    statusArray: [statusSchema] 
}); 

其中statusSchema

{ 
    topicId:{ 
     type: String, 
     optional: true 
    }, 
    someInfo:{ 
     type: Number, 
     optional: true, 
     decimal: true 
    }, 
    otherInfo:{ 
     type: Number, 
     optional: true 
    } 
} 

我想upsert - 用下面的方法流星代碼:

var upsertResult = BasicInfo.update({ 
    userId: this.userId, 
    statusArray: { 
    $elemMatch: { topicId : newStatus.topicId } 
    } 
}, { 
    $set: { 
    "statusArray.$.topicId": newStatus.topicId, 
    "statusArray.$.someInfo": newStatus.someInfo, 
    "statusArray.$.otherInfo": newStatus.otherInfo 
    }   
}, { 
    multi: true, 
    upsert: true 
}); 

但我總是收到一個錯誤:statusArray must be an array 我以爲通過添加$,我確定它被識別爲一個數組?我錯過了什麼?

+0

什麼是您的查詢'topicCompletion'場?你的意思是'statusArray'而不是? – Styx

+0

是的,抱歉 - 正在簡化代碼並錯過了。正在改變。 – ASX

+0

那麼,現在使用'$'是有道理的。雖然,你的意圖還不清楚。你想添加另一個對象到'statusArray'數組或更新其中的現有對象嗎? – Styx

回答

0

看起來(在您的澄清意見後),您要查找具體的文件userId和修改使用這些方案中的一個其statusArray陣列:

特別 topicId
  • 更新現有對象;
  • 如果數組沒有一個具有特定值的topicId,則添加一個新對象。

不幸的是,你不能使它工作只使用一個數據庫查詢,所以它應該是這樣的:

// try to update record 
const updateResult = BasicInfo.update({ 
    userId: this.userId, 
    'statusArray.topicId': newStatus.topicId 
}, { 
    $set: { 
    "statusArray.$": newStatus 
    }   
}); 

if (!updateResult) { 
    // insert new record to array or create new document 
    BasicInfo.update({ 
    userId: this.userId 
    }, { 
    $push: { 
     statusArray: newStatus 
    }, 
    $setOnInsert: { 
     // other needed fields 
    } 
    }, { 
    upsert: true 
    }); 
} 
+0

謝謝!非常清楚和有益的。對不起延遲嘗試此解決方案 - 積壓。 – ASX

+0

@ASX別擔心,我很高興它幫助你:) – Styx

-1

您的代碼處理StatusArray爲對象,

之前你做的更新插入,先建狀態數組,假設你的當前值是currentRecord

newStatusArray = currentRecord.statusArray 
newStatusArray.push({ 
    topicId: newStatus.topicId, 
    someInfo : newStatus.someInfo, 
    otherInfo: newStatus.otherInfo 
}) 

,並在更新插入,只需參考像這樣

$set: { statusArray: newStatusArray} 
+0

謝謝,但這需要我先拔出整個數組,然後將其重新保存到數據庫 - 這會變得非常低效沒有? – ASX

+0

效率不是主要問題,因爲它無論如何都必須檢索數據。除非數組中有成千上萬的元素,在這種情況下,您的數據設計是不正確的。有可能更新一個單獨的元素,在這種情況下,我想你會說'$ set:{「statusArray [x]」:newValues}'(其中x是要更新的元素的索引)您可以嘗試那 – Mikkel

+0

我看到你從mongo doco那裏得到'$'的東西。MiniMongo不支持完整的Mongo界面,所以Meteor基本上只提供一個子集(即使在服務器上) – Mikkel