Mongoose FindOneAndUpdate:更改值而不覆盖当前值

Mongoose FindOneAndUpdate: change value without overwriting current values

我有这个架构

{
        guildId: {
            type: String,
            required: true,
            unique: true
        },
        systems:{
            reactChat:{
                type: Array,
                required: true,
                default: []
            },
            notification:{
                tiktok:{
                    user:{
                        type: String
                    },
                    endCooldown: {
                        type: String,
                        default: '0'
                    }
                }
            }
        }

所以我想使用 findOneAndUpdate 更改系统 > 通知 > tiktok 中的 endCooldown 值。但是当我尝试这样做时,它会重置所有值,例如用户。 这是我正在使用的代码:

GuildSchema.findOneAndUpdate({guildId: id}, {
    systems:{
        notification:{
            tiktok:{
                endCooldown: String(Date.now() + 86400000) //24h
            }
            
        }
        
    }
}, () => {})

如何让它只改变 endCooldown?

在分析您的原始更新时,您实际上是在提交以下操作...

{
op: 'command',
ns: 'nodetest.Things',
command: {
  findAndModify: 'Things',
  query: { guildId: 'GOPd3ccG1f' },
  remove: false,
  new: false,
  upsert: false,
  fields: {},
  update: {
    '$set': { systems: { notification: { tiktok: [Object] } } }
  },
  lsid: { id: UUID("f4462722-1970-43c5-b2e1-b1cc5e38e9d0") },
  txnNumber: Long("2"),
  '$clusterTime': {
    clusterTime: Timestamp(2, 1630100100),
    signature: {
      hash: Binary(Buffer.from("005ff0e9abe7f7386825f291dfdf769ae050f08a", "hex"), 0),
      keyId: Long("6967052092213035012")
    }
  },
  '$db': 'nodetest'
},
keysExamined: 1,
docsExamined: 1,
nMatched: 1,
nModified: 1,
nUpserted: 0,
numYield: 0,
queryHash: '6D0EBC2A',
planCacheKey: '479D3C98',
locks: {
  ParallelBatchWriterMode: { acquireCount: { r: Long("2") } },
  ReplicationStateTransition: { acquireCount: { w: Long("3") } },
  Global: { acquireCount: { w: Long("2") } },
  Database: { acquireCount: { w: Long("2") } },
  Collection: { acquireCount: { w: Long("2") } },
  Mutex: { acquireCount: { r: Long("2") } }
},
flowControl: { acquireCount: Long("1"), timeAcquiringMicros: Long("1") },
readConcern: { level: 'local', provenance: 'implicitDefault' },
writeConcern: { w: 'majority', wtimeout: 0, provenance: 'implicitDefault' },
responseLength: 409,
protocol: 'op_msg',
millis: 57,
planSummary: 'IXSCAN { guildId: 1 }',
execStats: {
  stage: 'UPDATE',
  nReturned: 1,
  executionTimeMillisEstimate: 0,
  works: 1,
  advanced: 1,
  needTime: 0,
  needYield: 0,
  saveState: 0,
  restoreState: 0,
  isEOF: 1,
  nMatched: 1,
  nWouldModify: 1,
  nWouldUpsert: 0,
  inputStage: {
    stage: 'FETCH',
    nReturned: 1,
    executionTimeMillisEstimate: 0,
    works: 1,
    advanced: 1,
    needTime: 0,
    needYield: 0,
    saveState: 1,
    restoreState: 1,
    isEOF: 0,
    docsExamined: 1,
    alreadyHasObj: 0,
    inputStage: {
      stage: 'IXSCAN',
      nReturned: 1,
      executionTimeMillisEstimate: 0,
      works: 1,
      advanced: 1,
      needTime: 0,
      needYield: 0,
      saveState: 1,
      restoreState: 1,
      isEOF: 0,
      keyPattern: { guildId: 1 },
      indexName: 'guildId_1',
      isMultiKey: false,
      multiKeyPaths: { guildId: [] },
      isUnique: true,
      isSparse: false,
      isPartial: false,
      indexVersion: 2,
      direction: 'forward',
      indexBounds: { guildId: [ '["GOPd3ccG1f", "GOPd3ccG1f"]' ] },
      keysExamined: 1,
      seeks: 1,
      dupsTested: 0,
      dupsDropped: 0
    }
  }
},
ts: ISODate("2021-08-27T21:35:00.994Z"),
client: '127.0.0.1',
allUsers: [ { user: 'barry', db: 'admin' } ],
user: 'barry@admin'
}

此方法将 systems.notification.tiktok 对象设置为新对象,而不仅仅是字段 endCooldown。如果您只想编辑一个字段 endCooldown 然后提供有针对性的更新...

GuildSchema.findOneAndUpdate({guildId: id}, { "$set": { "systems.notification.tiktok.endCooldown": String(Date.now() + 86400000)}}, () => {});