How to multiple update a nested array within document at couchbase? - couchbase

I have a bucket called chat which includes document model like
{
"id": "50542400778551298_5001_abcdef",
"customer": {
...
},
"seller": {
...
},
"complaints": [],
"messages": [
{
"id": "2828911d-b96f-4b90-a52c-252d0324ab69",
"owner": "SELLER",
"content": "Merhabalar",
"readingDate": null,
"createdAt": "2022-06-27T09:16:42.49158+03:00"
},
{
"id": "8cd8c4b7-d599-4dfa-9fa7-be304a3b72b9",
"owner": "SELLER",
"content": "İlan hakkında detay bilgi verir misin?",
"readingDate": null,
"createdAt": "2022-06-27T09:17:43.329741+03:00"
},
{
"id": "4f0ae912-7d65-4e79-9058-2b048c4d9845",
"owner": "SELLER",
"content": "Huhuu",
"readingDate": null,
"createdDate": "2022-06-27T09:18:37.491531+03:00"
},
{
"id": "d2dd61b3-7ff1-4139-a411-9a917c00d4f3",
"owner": "SELLER",
"content": "Orada kimse var mı?",
"readingDate": null,
"createdAt": "2022-06-27T09:18:45.917564+03:00"
},
{
"id": "ea2d8dca-2f8c-4987-9c07-7515a6a0063f",
"owner": "SELLER",
"content": "Döner misininiz?",
"readingDate": null,
"createdAt": "2022-06-27T09:18:52.80337+03:00"
}
],
"status": "ACTIVE"
}
I want to update all messages readingDate a specific time like (2022-06-27T09:18:52.80337+03:00)
But I cannot find an easy way to accomplish this task.
I tried to write an N1QL like
UPDATE c.messages SET c.messages.readingDate = NOW_LOCAL()
FROM chat AS c
WHERE META().id = '50542400778551298_5001_abcdef';
but it is not working and gives error
[
{
"code": 3000,
"msg": "syntax error - at SET",
"query": "UPDATE c.messages SET c.messages.readingDate = NOW_LOCAL()\nFROM chat AS c \nWHERE META().id = '50542400778551298_5001_abcdef';"
}
]
I saw https://docs.couchbase.com/server/current/guides/bulk-operations.html.
As far as to my understanding, the general solution gets all messages and updates them based on cas.
But maybe I believe there is an easy way so I wanted to ask the StackOverflow community.

Thanks to this question I wrote n1ql like
UPDATE chat USE KEYS '50542400778551298_5001_abcdef'
SET c.readAt = NOW_LOCAL() FOR c IN messages END
RETURNING messages;

Related

IF statement in Couchbase Map of view - I'm sure I'm missing something simple

I'm trying to limit the map in my view to a specific set of documents by either having the id "startsWith" a string or based on there being a specific node in the JSON> I can't seem to get a result set once I add an IF statement. The reduce is a simple _count:
function(doc, meta) {
if (doc.metricType == "Limit_Exceeded") {
emit([doc.ownedByCustomerNumber, doc.componentProduct.category], meta.id);
}
}
I've also tried if (doc.metricType) and also if(meta.id.startsWith("Turnaway:")
Example Doc:
{
"OvidUserId": 26105400,
"id": "Turnaway:00005792:10562440",
"ipAddress": "111187081038",
"journalTurnawayNumber": 10562440,
"metricType": "Limit_Exceeded",
"oaCode": "OA_Gold",
"orderNumber": 683980,
"ovidGroupID": 3113900,
"ovidGroupName": "tnu999",
"ovidUserName": "tnu999",
"ownedByCustomerNumber": 59310,
"platform": "Lippincott",
"samlString": "",
"serialName": "00005792",
"sessionID": "857616ee-dab7-43d0-a08b-abb2482297dd",
"soldProduct": {
"category": "Multidisciplinary Subjects",
"name": "Custom Collection For CALIS - LWW TA 2020",
"productCode": "CCFCCSI20",
"productNumber": 33410,
"subCategory": "",
"subject": "Multidisciplinary Subjects"
},
"soldToCustomer": {
"customerNumber": 59310,
"keyAccount": false,
"name": "Tongji University"
},
"turnawayDateTime": "2022-05-04T03:01:44.600",
"usedByCustomer": {
"customerNumber": 59310,
"keyAccount": false,
"name": "Tongji University"
},
"usedByCustomerNumber": 59310,
"yearMonth": "202205"
},
"id": "Turnaway:00005792:10562440"
}
Thanks,
Gerry
Found it (of course after posting the question) The second component of the Key in the emit has to exist. I entered doc.componentProduct.category instead of doc.soldProduct.Category.

How to return result that belongs to user and restrict other data being sent in the result in FeathersJS?

I am new to feathersjs and I've breaking my head on how to restrict users from viewing other's data. For instance from postman when you do find/get(id) http://localhost/users you see list of all the users that are currently registered. However I would only like to return the current users data.
From:
{
"total": 2,
"limit": 10,
"skip": 0,
"data": [
{
"id": 1,
"email": "test#feathersjs.com",
"auth0Id": null,
"createdAt": "2020-02-01T23:16:30.833Z",
"updatedAt": "2020-02-01T23:16:30.833Z"
},
{
"id": 2,
"email": "test1#feathersjs.com",
"auth0Id": null,
"createdAt": "2020-02-01T23:31:50.904Z",
"updatedAt": "2020-02-01T23:31:50.904Z"
}
]
}
To:
{
"total": 1,
"limit": 10,
"skip": 0,
"data": [
{
"id": 1,
"email": "test#feathersjs.com",
"auth0Id": null,
"createdAt": "2020-02-01T23:16:30.833Z",
"updatedAt": "2020-02-01T23:16:30.833Z"
},
]
}
How do I filter result in the after hook function? Can someone please explain.
Answer:
Missed a basic step. All the find(), update() etc return result based on parent class. By Customizing find() method in your own class and using Sequlize.findOne({}) you can return the result you desire.
Damn! I was stupid to not read the docs fully.

N1QL query to filter JSON array in Couchbase server

I have the following array of data inside the data bucket SITES in my Couchbase server
"siteMaster": [
{
"sitename": "HTS_SITE_001",
"sitelink": "http://facebook.com",
"address" : "19/2, Bellandur, Bangalore India",
"filename": "site1.json",
"persons": 1,
"status": "70%",
"contact": "max.smith#honeywell.com",
}, {
"sitename": "HTS_SITE_002",
"sitelink": "http://facebook.com",
"address": "5th Avenue, New York",
"filename": "site2.json",
"persons": 1,
"status": "70%",
"contact": "john.smith#facebook.com",
}, {
"sitename": "HTS_SITE_003",
"sitelink": "http://facebook.com",
"address": "Palo Alto, California",
"filename": "site3.json",
"persons": 1,
"status": "80%",
"contact": "steve.jobs#apple.com",
}, {
"sitename": "HTS_SITE_004",
"sitelink": "http://facebook.com",
"address": "Bellandur, Bangalore",
"filename": "site4.json",
"persons": 1,
"status": "80%",
"contact": "max.mustermann#deutsche.com",
}
]
The N1QL query for
select * from SITES where status = "70%" should return me two rows, but unfortunately it is not returning any rows.
Where am I going wrong with the query ?
Please use the following query:
SELECT *
FROM SITES
WHERE ANY sm IN siteMaster SATISFIES sm.status = "70%" END;
You can also create the following array index to speed up the query:
CREATE INDEX idx ON SITES( DISTINCT ARRAY sm.status FOR sm IN siteMaster END );

ember data custom serializer for a json

I have a Session object I want to model in Ember data. (actually display sessions but it's the same)
The JSON from the server looks like this (cannot be changed):
{
"metadata": {
"page": 1,
"page_size": 100,
"total_num_objects": 7,
"total_num_pages": 1
},
"result": [
{
"api_path": "/rest/sessions/2",
"end_time": 1412687629.42063,
"hostname": "127.0.0.1",
"id": 2,
"logical_id": "c6656738-4e23-11e4-9017-685b35b63131_0",
"product_name": null,
"product_revision": null,
"product_version": null,
"start_time": 1412687629.26851,
"status": "SUCCESS",
"type": "session",
"user_name": null
},
{
"api_path": "/rest/sessions/3",
"end_time": 1412688377.15329,
"hostname": "127.0.0.1",
"id": 3,
"logical_id": "84707366-4e25-11e4-a659-685b35b63131_0",
"product_name": null,
"product_revision": null,
"product_version": null,
"start_time": 1412688377.11507,
"status": "SUCCESS",
"type": "session",
"user_name": null
},
...
I realize I need to write a custom RESTSerializer but I can't figure out what do I need to do in order go get rid of metadata + make ember realize that result is actually a session.
Side question:
Can I make the DS.Model.extend attributes like what I get from the API or do I must use CamelCase and use normalizeHash
You'd probably need to do something like this:
App.SessionSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload) {
return {
sessions: payload.result
};
}
});
See: http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_normalizePayload
Regarding your other issue, look at DS.ActiveModelAdapter / ActiveModelSerializer. ActiveModelSerializer handles the underscore convention in the JSON.

Backbone.js Collections

I am working with backbone.js. I am trying to send a request to restful service i am getting the resultset as json object as shown
{
"Msgs": [
"Alert",
"Not"
],
"MessageStatus": [
"Active",
"Inactive"
],
"date": {
"From": "2013-04-25",
"To": "2013-06-25"
},
"Mlist": {
"Status": "PND",
"Role": "Admin,User",
"To": "2013-06-24",
"Id": 6,
"Datecreated": "2013-06-24",
"Title": "Title5",
"From": "2013-06-20"
}
}.
I am putting the json object extracting and setting it to collection but I am not able to get particular model from the collection with specific id.
If you want to make your model can be identified with id. You have to set the id in the attributes hash:
{
"id": 1001,
"Msgs": [
"Alert",
"Not"
],
"MessageStatus": [
"Active",
"Inactive"
],
"date": {
"From": "2013-04-25",
"To": "2013-06-25"
},
"Mlist": {
"Status": "PND",
"Role": "Admin,User",
"To": "2013-06-24",
"Id": 6,
"Datecreated": "2013-06-24",
"Title": "Title5",
"From": "2013-06-20"
}
}
Then using backbone collection "findWhere" method to get the specific id model.
//assume msgCollection is which you put the models
var model = msgCollection.findWhere({id: 1001});
Hope this is helpful for you.
I think you need to set your model and parse your input data. Checkout http://backbonejs.org/#Collection-model, http://backbonejs.org/#Model-parse and http://backbonejs.org/#Collection-parse.