arangodb 从提交日志中获取文档更新日期
arangodb get document update date from commit log
如果有提交日志这样的东西,是否可以从Arangodb提交日志中获取记录更新数据。我们有几个文件更新了,但我们确实更新了他们的修改日期字段。然而,我们想要检索自某个日期以来的所有 updated/changed 个文档。
有两种解决方法:
方案一:
第一个解决方案是不使用提交日志,而是 运行 在 collection 上进行 AQL 查询并在 modified
日期字段上进行过滤。如果 modified
字段上有排序索引(即跳过列表索引),这将是有效的。
可以在以下设置脚本中找到此设置的示例,该脚本使用随机修改日期的 50K 文档填充 collection test
:
/* use some fixed base date to make query produce results */
var baseDate = 1478779081650; /* 2016-11-10T11:58:01.650Z */
db._create("test");
db.test.ensureIndex({ type: "skiplist", fields: [ "modified" ]});
/* create 50,000 documents with modified dates between
2016-11-10T11:58:01.650Z and up to two years in the past */
for (var i = 0; i < 50000; ++i) {
db.test.insert({ value: i, modified: new Date(baseDate - Math.floor(Math.random() * 1000 * 60 * 60 * 24 * 365 * 2)).toISOString() });
}
然后使用 AQL straight-forward 查找 modified
日期高于特定值的文档:
var query = "FOR doc IN test FILTER doc.modified >= @date RETURN doc";
/* find all documents modified since 2016-11-09T12:00:00.000Z */
var docs = db._query(query, { date: "2016-11-09T12:00:00.000Z" }).toArray();
require("internal").print(docs);
也可以对日期范围进行查询,例如
var query = "FOR doc IN test FILTER doc.modified >= @from && doc.modified <= @to RETURN doc";
var docs = db._query(query, { from: "2016-11-09T00:00:00.000Z", to: from: "2016-11-09T23:59:59.999Z" }).toArray();
require("internal").print(docs);
方案二:
第二种解决方案是使用 ArangoDB 也通过其 HTTP API 公开的 WAL 更改日志。但这要复杂得多,需要在客户端保持状态。
基本思路是查询 /_api/replication/logger-follow
处的 WAL 更改日志 API 以获取给定的 collection。这个 API 调用可以被赋予初始 tick 值。这控制请求将从更改日志中的何处开始查找。一开始这个tick的值不清楚,所以干脆省略了。
使用 curl,对 collection test
的调用将是:
curl -X GET "http://127.0.0.1:8529/_db/_system/_api/replication/logger-follow?collection=test" --basic --user "root:" --dump -
所有对此 API 的调用都会产生一些 HTTP headers,其中包含状态信息和按时间顺序排列的 collection 的 WAL 条目,例如
...
X-Arango-Replication-Checkmore: true
X-Arango-Replication-Lastincluded: 6103060
X-Arango-Replication-Lasttick: 6251758
...
{"tick":"6101295","type":2000,"database":"1","cid":"6101294","cname":"test","data":"cid":"6101294","deleted":false,"doCompact":true,"indexBuckets":8,"isSystem":false,"isVolatile":false,"maximalSize":33554432,"name":"test","type":2,"version":5,"waitForSync":false}}
{"tick":"6101298","type":2100,"database":"1","cid":"6101294","cname":"test","data":{"fields":["modified"],"id":"6101297","sparse":false,"type":"skiplist","unique":false}}
{"tick":"6101302","type":2300,"tid":"0","database":"1","cid":"6101294","cname":"test","data":"_id":"test/6101300","_key":"6101300","_rev":"6101300","modified":"2015-06-26T14:18:30.732Z","value":0}}
{"tick":"6101305","type":2300,"tid":"0","database":"1","cid":"6101294","cname":"test","data":"_id":"test/6101304","_key":"6101304","_rev":"6101304","modified":"2016-11-09T07:14:08.146Z","value":1}}
{"tick":"6101308","type":2300,"tid":"0","database":"1","cid":"6101294","cname":"test","data":"_id":"test/6101307","_key":"6101307","_rev":"6101307","modified":"2015-05-14T04:45:01.202Z","value":2}}
...
可以看出,更改日志不仅包含文档的 insert/update 操作,还包含 collection 的创建和索引的创建。它还将包含所有删除操作和其他更改 collection.
的 meta-data 的操作
使用更改日志结果,您现在可以在客户端过滤它们 type
2300,这是一个文档插入或更新操作,然后查看 data
.modified
每个返回的文件。然后您可以使用满足您搜索条件的文档。
请注意,请求的结果可能不包含所有操作,但可能只包含其中的一小部分。可能需要从服务器获取更多数据。这可以通过再次调用 API 来完成,现在使用 X-Arango-Replication-Lastincluded
HTTP 响应 header 的值作为 tick
值,例如
curl -X GET "http://127.0.0.1:8529/_db/_system/_api/replication/logger-follow?collection=test&from=6103060" --basic --user "root:" --dump -
这将产生更多的操作。您可以一次又一次地调用 API,直到它不再产生任何结果并且 X-Arango-Replication-Checkmore
HTTP 响应 header 的值变为 false
。这意味着您暂时已经获取了所有操作。
此解决方案要求客户端可能发出多个 HTTP 请求并保持状态(最后获取的 tick
值),因此它不像 AQL-based 解决方案那样易于使用。
如果有提交日志这样的东西,是否可以从Arangodb提交日志中获取记录更新数据。我们有几个文件更新了,但我们确实更新了他们的修改日期字段。然而,我们想要检索自某个日期以来的所有 updated/changed 个文档。
有两种解决方法:
方案一:
第一个解决方案是不使用提交日志,而是 运行 在 collection 上进行 AQL 查询并在 modified
日期字段上进行过滤。如果 modified
字段上有排序索引(即跳过列表索引),这将是有效的。
可以在以下设置脚本中找到此设置的示例,该脚本使用随机修改日期的 50K 文档填充 collection test
:
/* use some fixed base date to make query produce results */
var baseDate = 1478779081650; /* 2016-11-10T11:58:01.650Z */
db._create("test");
db.test.ensureIndex({ type: "skiplist", fields: [ "modified" ]});
/* create 50,000 documents with modified dates between
2016-11-10T11:58:01.650Z and up to two years in the past */
for (var i = 0; i < 50000; ++i) {
db.test.insert({ value: i, modified: new Date(baseDate - Math.floor(Math.random() * 1000 * 60 * 60 * 24 * 365 * 2)).toISOString() });
}
然后使用 AQL straight-forward 查找 modified
日期高于特定值的文档:
var query = "FOR doc IN test FILTER doc.modified >= @date RETURN doc";
/* find all documents modified since 2016-11-09T12:00:00.000Z */
var docs = db._query(query, { date: "2016-11-09T12:00:00.000Z" }).toArray();
require("internal").print(docs);
也可以对日期范围进行查询,例如
var query = "FOR doc IN test FILTER doc.modified >= @from && doc.modified <= @to RETURN doc";
var docs = db._query(query, { from: "2016-11-09T00:00:00.000Z", to: from: "2016-11-09T23:59:59.999Z" }).toArray();
require("internal").print(docs);
方案二:
第二种解决方案是使用 ArangoDB 也通过其 HTTP API 公开的 WAL 更改日志。但这要复杂得多,需要在客户端保持状态。
基本思路是查询 /_api/replication/logger-follow
处的 WAL 更改日志 API 以获取给定的 collection。这个 API 调用可以被赋予初始 tick 值。这控制请求将从更改日志中的何处开始查找。一开始这个tick的值不清楚,所以干脆省略了。
使用 curl,对 collection test
的调用将是:
curl -X GET "http://127.0.0.1:8529/_db/_system/_api/replication/logger-follow?collection=test" --basic --user "root:" --dump -
所有对此 API 的调用都会产生一些 HTTP headers,其中包含状态信息和按时间顺序排列的 collection 的 WAL 条目,例如
...
X-Arango-Replication-Checkmore: true
X-Arango-Replication-Lastincluded: 6103060
X-Arango-Replication-Lasttick: 6251758
...
{"tick":"6101295","type":2000,"database":"1","cid":"6101294","cname":"test","data":"cid":"6101294","deleted":false,"doCompact":true,"indexBuckets":8,"isSystem":false,"isVolatile":false,"maximalSize":33554432,"name":"test","type":2,"version":5,"waitForSync":false}}
{"tick":"6101298","type":2100,"database":"1","cid":"6101294","cname":"test","data":{"fields":["modified"],"id":"6101297","sparse":false,"type":"skiplist","unique":false}}
{"tick":"6101302","type":2300,"tid":"0","database":"1","cid":"6101294","cname":"test","data":"_id":"test/6101300","_key":"6101300","_rev":"6101300","modified":"2015-06-26T14:18:30.732Z","value":0}}
{"tick":"6101305","type":2300,"tid":"0","database":"1","cid":"6101294","cname":"test","data":"_id":"test/6101304","_key":"6101304","_rev":"6101304","modified":"2016-11-09T07:14:08.146Z","value":1}}
{"tick":"6101308","type":2300,"tid":"0","database":"1","cid":"6101294","cname":"test","data":"_id":"test/6101307","_key":"6101307","_rev":"6101307","modified":"2015-05-14T04:45:01.202Z","value":2}}
...
可以看出,更改日志不仅包含文档的 insert/update 操作,还包含 collection 的创建和索引的创建。它还将包含所有删除操作和其他更改 collection.
的 meta-data 的操作使用更改日志结果,您现在可以在客户端过滤它们 type
2300,这是一个文档插入或更新操作,然后查看 data
.modified
每个返回的文件。然后您可以使用满足您搜索条件的文档。
请注意,请求的结果可能不包含所有操作,但可能只包含其中的一小部分。可能需要从服务器获取更多数据。这可以通过再次调用 API 来完成,现在使用 X-Arango-Replication-Lastincluded
HTTP 响应 header 的值作为 tick
值,例如
curl -X GET "http://127.0.0.1:8529/_db/_system/_api/replication/logger-follow?collection=test&from=6103060" --basic --user "root:" --dump -
这将产生更多的操作。您可以一次又一次地调用 API,直到它不再产生任何结果并且 X-Arango-Replication-Checkmore
HTTP 响应 header 的值变为 false
。这意味着您暂时已经获取了所有操作。
此解决方案要求客户端可能发出多个 HTTP 请求并保持状态(最后获取的 tick
值),因此它不像 AQL-based 解决方案那样易于使用。