CouchDB设计视图未返回所有早于N秒的记录

huangapple go评论57阅读模式
英文:

CouchDB design view not returning all the records older than N seconds

问题

我在使用CouchDB设计时遇到了一个问题,应该根据文档的created属性返回早于5秒的记录。文档不断添加到mydb数据库中。

由于某种原因,早于当前日期-5秒的创建日期小于当前日期的文档没有返回。

这是我如何添加文档的方式:

...
timestamp==$(echo $(( $(date +%s) * 1000 )))
...
curl -X POST -H "Content-Type: application/json" -d "{\"created\": ${timestamp}}" http://localhost:5984/mydb -u "admin:YOURPASSWORD"

我如何使用视图查询:

curl -X GET -u "admin:YOURPASSWORD" "http://localhost:5984/mydb/_design/nonce/_view/older_than?limit=100"

如果只添加了几个文档,那么一切正常,但反复这样做时,返回的记录数量不符合预期。

有任何想法我可能做错了什么?

这是专门创建的示例项目,用于了解我在GitHub上做错了什么(上面的示例已自动化,并有一个相应的GO方法,应该删除返回的记录):

https://github.com/igorrendulic/couchdb-test

英文:

I'm experiencing a problem using CouchDB design which should return records older than 5 seconds based on created property of documents. The documents are continuously added to the mydb database.

For some reason the documents with lesser created date than current date - 5 seconds are not returned.

This is how I add a document:

...
timestamp==$(echo $(( $(date +%s) * 1000 )))
...
curl -X POST -H "Content-Type: application/json" -d "{\"created\": ${timestamp}}" http://localhost:5984/mydb -u "admin:YOURPASSWORD" 

How I query using the view:

curl -X GET -u "admin:YOURPASSWORD" "http://localhost:5984/mydb/_design/nonce/_view/older_than?limit=100"

If added just a few documents, then things work ok, but repeatedly doing so it doesn't returned expected number of records.

Any ideas what I might be doing wrong?

Here is the example project specifically created to learn what I'm doing wrong on GitHub (above examples automated and a corresponding GO method that should delete returned records:

https://github.com/igorrendulic/couchdb-test

答案1

得分: 1

重要的是要理解emit函数是在创建或更新文档时调用的,而不是在查询时调用的。

emit函数

function(doc) 
{ 
    var now = Date.now() - (5 * 1000);
    if (doc.created < now) {
        emit(doc.created, doc._rev); 
    }
}

从文档的created字段中减去5秒(假设该字段存在),然后将该值索引化,这似乎没有用处。

如果解决方案是返回具有created字段值比当前时间少5秒或更多的最新文档,那么这个简单的emit就足够了(可能对其他查询提供更多的实用性)。

function(doc) 
{    
    if (doc.created) {
        emit(doc.created, doc._rev); 
    }
}

CouchDB的排序规范导致较小的数值位于索引的开头,因此查询需要反向排序并提供所需的时间窗口,比如当前时间减去5秒:

?descending=true&start_key={epoch_time_ms}&limit=100

该查询将返回最多100个具有created小于或等于epoch_time_ms的文档,最新的文档首先出现在结果集中。

我必须补充说明,存储_rev似乎有点模糊,因为可以从结果文档中获取该信息。

英文:

It is key to understand that the emit function is invoked during indexing of a document at creation or update time rather than at query time.

The emit function

function(doc) 
{ 
    var now = Date.now() - (5 * 1000);
    if (doc.created < now) {
        emit(doc.created, doc._rev); 
    }
}

Is subtracting 5 seconds from the document's created field (notably assuming that field exists) and indexing the value, which does not seem useful.

If the solution is to return the most recent documents that have a created field value that is 5 or more seconds less than current time, then this simple emit will suffice (and may provide more utility for other queries)

function(doc) 
{    
    if (doc.created) {
        emit(doc.created, doc._rev); 
    }
}

CouchDB's collation specification result in smaller numeric values to be at the beginning of the index so the query needs to reverse the sort and provide the desired window of time, say in this case current time less 5 seconds:

?descending=true&start_key={epoch_time_ms}&limit=100

That query will return up to 100 documents with created less than or equal to epoch_time_ms with the most recent document first in the result set.

I must add, storing the _rev seems nebulous as that information can be gained from the result document.

huangapple
  • 本文由 发表于 2023年8月4日 01:32:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830383.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定