Filtering posts by timestamp and userId

2019-08-12 06:59发布

I have the following object in Couchbase:

{
   "postReplyId": "Reply_9AE1F47E585522FD1D2EFFEA7671C0855BBFDA991698B23886E37D1C65DAC8AF_1375468399745",
   "userId": "User_9AE1F47E585522FD1D2EFFEA7671C0855BBFDA991698B23886E37D1C65DAC8AF",
   "postId": "Message_9AE1F47E585522FD1D2EFFEA7671C0855BBFDA991698B23886E37D1C65DAC8AF_1375457606125",
   "post_reply_message": "Testing",
   "attachments": {
   "images": [
   ],
   "audio": [
   ],
   "videos": [
   ]
   },
   "upVoters": [
   ],
   "downVoters": [
   ],
   "upVotes": 0,
   "report": 0,
   "reporters": [
   ],
   "timestamp": 1375468399745,
   "mtype": "reply"
}

I would like to have a view and return all the posts created during the last 30 minutes by the user x

I did:

function (doc, meta) {
  if(doc.mtype == "reply") {
    var dt = new Date();
    if((dt.getTime() - doc.timestamp) < 1800000 )
    emit(doc.userId, doc);
  }
}

and i pass the userIds as multiple keys in the URL, but I get old results

Can someone suggest a solution?

1条回答
我命由我不由天
2楼-- · 2019-08-12 07:43

A view runs as documents are added/modified, and only upon request or when automatically updated. It doesn't rerun constantly, and more importantly, it does not re-run for already added documents. So, as written your view would only contain old results.

You need to emit all documents and include the timestamp as part of the emit, so that you can use that as part of the query to the view (a time range).

So, in your emit function, you might instead (untested code):

function (doc, meta) {
  if (doc.mtype === "reply") {
    // dt will be when the document is processed by the view, which may
    // not when the document was added.
    var dt = new Date();  
    var year = dt.getFullYear();
    var month = dt.getMonth() + 1; // make month 1-12
    var day = dt.getDate();
    var hours = dt.getHours();
    var minutes = dt.getMinutes();
    var seconds = dt.getSeconds();

    // emit the full key, including the user id and the date of the document.
    emit([doc.userId, year, month, day, hours, minutes, seconds], doc._id);
  }
}

Then your query might be like this range (broken into several lines for readability):

/salamis_db/_design/docs/_view/by_user_date?
     startkey=["the-userId", 2013, 8, 7, 10, 30, 0]
     &endkey=["the-userId", 2013, 8, 7, 11, 00, 00]

Although endkey wouldn't strictly be necessary, I've left it in for clarity.

Because of the way Couchbase views work, a view may not always contain all data though (from here):

Irrespective of the stale parameter, documents can only be indexed by the system once the document has been persisted to disk. If the document has not been persisted to disk, use of the stale will not force this process. You can use the observe operation to monitor when documents are persisted to disk and/or updated in the index.

Also, note that documents are not immediately added to the view by default. Read this for more information.

查看更多
登录 后发表回答