问题
I am trying to create a Rethinkdb database with an audit trail in node.js.
My table contains the following fields:
Order-ID Quantity Price Status Timestamp
I have a file which I upload the following data as an example:
Order-ID......Quantity.....Price
1....................'1000'..........100
2....................'500'............100
3....................'1575'..........100
When I upload in an empty table all these rows will be inserted along with the time&date and the status set to 'active'.
Let's assume I upload the file again with updated data (the quantity of order-id 1 is changed), for example:
Order-ID......Quantity.....Price
1....................'1010'..........100
2....................'500'............100
3....................'1575'..........100
The Rethinkdb query should set status of the row with order-ID 1 to 'replaced' and update the timestamp. Next it should insert a new row with the updated data, set status to 'active' and timestamp it.
So my table with the new updated data should look like this:
Order-ID......Quantity.....Price.....status.............timestamp
1....................'1000'..........100......'replaced'.....'12:03AM 4/22/2016'
1....................'1010'..........100.......'active'........'12:03AM 4/22/2016'
2....................'500'............100......'active'.........'12:00AM 4/22/2016'
3....................'1575'..........100......'active'.........'12:00AM 4/22/2016'
Now I have an audit trail to see what and when it was changed/inserted.
Is this possible with rethinkdb in node.js?
@dalanmiller
I tried to test the codes, but I don't understand the prepend and the 0th.
One of the assumption you made is that only quantity can change. What happens if Price could also change or both of them at once? It is possible I would like to add more fields/columns which can also be updated over time.
It is also possible the order changes couple times.
The data is in the variable called 'message'.
This is what I have for now and it doesn't update:
r.db('testing').table('orders').filter({Order_ID: message[ticks].Order_ID}).count().run() //count how many rows with this Order_ID
.then(function(feed){
if (JSON.stringify(feed)==1){ //check if the order_id already exist
r.db('testing').table('orders').filter({Order_ID: message[ticks].Order_ID}).update(message[ticks]).do(
function (post) {
return r.branch(post('replaced').eq(0),
false, //if nothing changes, leave it as it is
r.db('testing').table('orders').post('orders').prepend(post('orders').nth(0).merge({message[ticks].Quantity})) // <-- I don't understand how this works
)
}).run()
}
else if (JSON.stringify(feed)==0){
//new order. Insert the order
message[ticks].Timestamp = new Date(); //add timestamp
message[ticks].Status = 'Active'; // add status as 'Active'
r.db('testing').table('orders').insert(message[ticks]).run()
}
回答1:
This is definitely possible to do with Node and RethinkDB.
One way to do this is to have an array of objects within the document which represents the order itself. For this application, we're going to assume that the object in the 0th index of the order_state
array is the most recent version of the order.
Simplistically, once an order is made it could look something like this:
{
order_id: 1,
order_state: [ { quantity: 20, price: 100, timestamp: "12:03AM 4/22/2016"} ]
}
And this can be done by the ReQL query:
r.db("marketplace").table("orders").insert({ above_obj })
Now say if the person who made the order decides to go back and change their order to 40
instead of 20
.
r.db("marketplace").table("orders").get( id of document ).update( (doc) => {
return {
orders: doc('orders').prepend(doc('orders').nth(0).merge({ quantity: 40}))
}
})
Here we are first getting the document with the .get()
command then .update
ing it. We then return an object with key { orders: }
so that the orders
field in the original will be replaced. We take the original value of orders
and .prepend()
the array with a copy of the previous 0th element which we modify with .merge
to have the updated quantity of 40
.
{
id: "a randomly generated uuid",
order_id: 1,
orders: [
{
quantity: 40, price: 100, timestamp: "12:35AM 4/22/2016" // Newest modification
},
{
quantity: 20, price: 100, timestamp: "12:03AM 4/22/2016" // Original order
}
]
}
One drawback here is that if you are expecting thousands of modifications to an order, you will want to put that into another table and then do some sort of join between the two. If average order modifications stay relatively small, say < 100 then this schema should be fine for you.
来源:https://stackoverflow.com/questions/36781432/rethinkdb-audit-trail-with-field-timestamp-and-status-when-update-insert