CouchDB: Return Newest Documents of Type Based on Timestamp

前端 未结 3 434
清酒与你
清酒与你 2021-01-15 14:33

I have a system that accepts status updates from a variety of unique sources, and each status update creates a new document in the following structure:

{
 \"         


        
3条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-15 15:21

    CouchDB map/reduce is incremental which basically means the results are always cached, so subsequent requests for the same view (even with different search parameters) run "for free" (or in logarithmic time).

    However, that is not strictly true with reduce groups. Sometimes partial results must be re-reduced on the fly. Maybe that is what you are hitting.

    Instead, how about a map view (i.e. no reduce function) that emits rows like this, with an array as the key:

    // Row diagram (pseudo-code, just to show the concept).
    // Key                    , Value
    // [source_id, timestamp] , null // value is not very important in this example
    ["truck1231", 13023123123], null
    ["truck1231", 13023126723], null
    ["truck5555", 13023126123], null
    ["truck6666", 13023000000], null
    

    Notice how all timestamps for a source "clump" together. (Actually, they collate.) To find the latest timestamp for "truck1231", just requests the last row in that "clump". To do that, do a descending query, from the end, with a limit=1 argument. To specify the "end", use the {} "high key" value as the second element in the key (see the collation link for details).

    ?descending=true&limit=1&startkey=["truck1231",{}]
    

    (Actually, since your timestamps are integers, you could emit their negation, e.g. -13023123123. That will simplify your query a bit but—I don't know—that seems like playing with fire to me.)

    To produce these kinds of rows, us a map function like this:

    function(doc) {
      // Emit rows sorted first by source id, and second by timestamp
      if (doc.type == "status_update" && doc.timestamp) {
        emit([doc.source_id, doc.timestamp], null) // Using `doc` as the value would be fine too
      }
    }
    

提交回复
热议问题