MongoDB更改流仅显示选定的字段

时间:2018-03-07 13:38:41

标签: mongodb watch changestream

我正在尝试了解MongoDB中的更改流。

我正在尝试仅显示更新文档的某些字段。

所以我做了:

option={ 'full_document':'updateLookup' }
collection.watch([{"$match"  : { "operationType" : "update" }}] , **option)

正在发挥作用。

现在我想只显示一些字段。

我试过了:

collection.watch([{"$match"  : { "operationType" : "update" }},{"$project":{"_id":1}}] , **option)

collection.watch([{"$match"  : { "operationType" : "update" }}],option).aggregate({"$project":{"_id":1}})

但它们都不起作用。

如何仅显示所选字段?

1 个答案:

答案 0 :(得分:2)

Change Event documentation page,更改流将输出此文档:

{
   _id : { <BSON Object> },
   "operationType" : "<operation>",
   "fullDocument" : { <document> },
   "ns" : {
      "db" : "<database>",
      "coll" : "<collection"
   },
   "documentKey" : { "_id" : <ObjectId> },
   "updateDescription" : {
      "updatedFields" : { <document> },
      "removedFields" : [ "<field>", ... ]
   }
}

也就是说,如果你在watch()方法中没有放置任何内容,那么该文档将成为输出。

然后,您可以使用aggregation pipeline stages过滤/修改此文档。

例如,如果您只想查看插入/更新文档中的字段_idab,那么管道将是(使用Python):

with db.test.watch([
    {'$project': {
        'fullDocument_id':'$fullDocument._id',
        'a':'$fullDocument.a',
        'b':'$fullDocument.b'}}], full_document='updateLookup') as stream:
    for change in stream:
        print change

将数据插入MongoDB:

> db.test.insert({a:1, b:1, c:1, d:1})

更改流将输出:

{'a': 1.0,
 'fullDocument_id': ObjectId('5aa0c2300551e941c6958f86'),
 '_id': <BSON object>,
 'b': 1.0}

注意:我将插入的文档_id投影到fullDocument_id。您可以将其投影到_id(例如_id: '$fullDocument._id'),但您将丢失更改流的原始_id字段,其中包含resume token

注意:创建流时我也使用了参数full_document='updateLookup'。否则,完整文档将不会显示在update事件中。这在Change Event page

中有解释

注意:上面的示例用于插入文档,但您可以在$match: {operationType: 'update'}阶段之前使用$project阶段轻松定制更新。

注意:更新事件时返回的fullDocument字段包含多数提交给副本集成员的文档的已查找版本。这可能是也可能不是被修改的文档的版本。更新操作之间以及将更改流返回到客户端之间的任何其他交错操作可能已经改变了文档的版本。例如,删除事件可能会导致fullDocument字段为null。有关详细信息,请参阅Lookup Full Document for Update Operations