FindAndModify在哪里适合CQRS?

tug*_*erk 5 c# mongodb cqrs

在我当前的应用程序中,我FindAndModify对MongoDB服务器进行了以下MongoDB 调用

public static TEntity PeekForRemoveSync<TEntity>(this MongoCollection<TEntity> collection, string reason)
    where TEntity : class, IEntity, IUpdatesTrackable, ISyncable, IDeletable, IApprovable
{
    if (reason == null)
    {
        throw new ArgumentNullException(nameof(reason));
    }

    IMongoQuery query = Query.And(
        Query<TEntity>.EQ(e => e.SyncInfo.IsDirty, true),
        Query<TEntity>.NE(e => e.Deletion, null),
        Query<TEntity>.NE(e => e.Approval, null),
        Query<TEntity>.EQ(e => e.SyncInfo.HumanInvestigateFlag, null),
        Query.Or(
            Query<TEntity>.EQ(e => e.SyncInfo.IsUpdateInProgress, false),
            Query<TEntity>.LT(e => e.SyncInfo.UpdateStartInfo.OccuredOn, DateTime.UtcNow.AddSeconds(-SyncConstants.PeekExpireTimeInSeconds))
        ),
        Query<TEntity>.LTE(e => e.SyncInfo.PeekedCount, MaxPeekedCount)
    );

    return PeekForSync(collection, query, reason);
}

private static TEntity PeekForSync<TEntity>(this MongoCollection<TEntity> collection, IMongoQuery query, string reason)
    where TEntity : class, IEntity, IUpdatesTrackable, ISyncable, IDeletable
{
    UpdateBuilder<TEntity> update = Update<TEntity>
        .Inc(e => e.SyncInfo.PeekedCount, 1)
        .Set(e => e.SyncInfo.UpdateStartInfo, new OccuranceWithReason(reason))
        .Set(e => e.SyncInfo.IsUpdateInProgress, true);

    SortByBuilder<TEntity> sort = SortBy<TEntity>.Descending(e => e.LastUpdatedOn);

    FindAndModifyArgs fmArgs = new FindAndModifyArgs
    {
        Query = query,
        Update = update,
        SortBy = sort,
        VersionReturned = FindAndModifyDocumentVersion.Modified
    };

    FindAndModifyResult result = collection.FindAndModify(fmArgs);

    return result.ModifiedDocument != null
        ? result.GetModifiedDocumentAs<TEntity>()
        : null;
}
Run Code Online (Sandbox Code Playgroud)

我是否用MongoDB重新发明了另一个队列系统?这不是我的意图,但它就是它的意思.忽略那里的业务逻辑.

在CQRS中,查询和命令意味着以下(我相信):

命令:更改系统状态并不返回任何值.

查询:不更改系统状态并返回一些值.

如果是这种情况,我的上述FindAndModify电话(或任何其他类似的查询)适合哪里?

Mat*_*int 3

这可能会有些固执己见,但这是我的看法:

CQRS 命令通常应该对单个聚合实体采取一些特定操作。

命令示例:

  • 更改人名
  • 下订单
  • 删除帐户

如果在命令处理程序实现的实现中需要数据,则该数据应该来自严格通过其文档 ID 找到的文档。(或者ObjectId用蒙古语)

在某些文档数据库中,通过 ID 以外的其他内容进行查询是最终一致的操作。如果您依靠查询结果来决定要执行的操作,那么当索引过时时,您可能会丢失一些项目。您如何知道该命令已针对所有数据真正完成?你不会。

如果查询结果确实完全一致(可能在 Mongo 中,我不是 100% 确定),即使这样,你也会遇到时间问题。您可能打算对与查询匹配的所有数据进行操作,但也许几毫秒后会插入与查询匹配的新数据。由于操作的范围不受特定文档(或一组文档)的限制,因此您实际上无法知道是否真正完成

一般来说,我认为从 CQRS 命令中执行查询(除了文档 ID 之外的任何内容)并不是一个好主意。

FindAndModify看起来是用来打补丁的。您可能确实需要偶尔这样做,但它不符合 CQRS 模式。我会将其保留用于维护任务 - 在系统的主要 CQRS 部分之外。