Update specific object in the array of object in couchbase 4.1 - couchbase

I have following doc with doc key cart::16
{
"_type": "NSCart",
"_metadata": {
"created_at": 1473075845614,
"updated_at": null
},
"_id": "f28bc609-6aba-47e5-8e83-5bee2397566f",
"userId": "B1HvmsLj57c9235c",
"items" : [{
"itemId": "N1d55j8m4xr",
"seller": "ByD9T4Ks57cbbd8e",
"license": null,
"basePrice": 0
},{
"itemId": "L9nd6Dswl4v",
"seller": "ByD9T4Ks57cbbd8e",
"license": E122,
"basePrice": 500,
"eCharge": 10,
"total": 510
}]
}
now i want to update a doc where item id is N1d55j8m4xr like this
{
"itemId": "N1d55j8m4xr",
"seller": "ByD9T4Ks57cbbd8e",
"license": null,
"basePrice": 590,
"eCharge": 18,
"total": 608
}
There is method array_replace in n1ql but didn't get desired output.

Use the following syntax from the N1QL documentation.
UPDATE mybucket SET x.field = newvalue FOR x IN myarray WHEN x.id = myid END;

update `buc_name` set items =
CASE
WHEN "N1d55j8m4xr" IN items [*].itemId
THEN (ARRAY CASE WHEN itm.itemId = "N1d55j8m4xr"
THEN {
"itemId": "N1d55j8m4xr",
"seller": "ByD9T4Ks57cbbd8e",
"license": null,
"basePrice": 590,
"eCharge": 18,
"total": 608
}
ELSE itm
END
FOR itm IN items END) end where "N1d55j8m4xr" IN items [*].itemId

Related

How to multiple update a nested array within document at 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;

Excel JSON VBA Parsing - Determining if an array is empty

I am trying to parse a JSON response. I cannot use the VBA-JSON library. I need to check to see if a nested array is empty or null. I keep getting this error:
Example JSON:
{
"gardenAssets": [],
"gardenAssetsAlertCount": 0,
"gardenAssetsCount": 0,
"gardenAssetsErrorCount": 0,
"locationsSummaries": [
{
"locations": [
{
"auditOrder": "102",
"code": "POT 102",
"name": "POT 102",
"type": "ProcessingLocation",
"gardenAssets": [
{
"annotation": "Pallets",
"broker": {
"code": "TMTO",
"isOwner": null,
"name": null
},
"datetimeOfArrivalIngarden": 1622754283.937,
"id": "crusaf",
"isSealable": true,
"load": null,
"mastergardenCode": null,
"name": null,
"owner": {
"code": "SUN",
"isOwner": null,
"name": null
}
}
]
},
{
"auditOrder": "103",
"code": "POT 103",
"description": "POT 103",
"id": "110746",
"name": "POT 103",
"type": "ProcessingLocation",
"gardenAssets": []
},
{
"auditOrder": "104",
"code": "POT 104",
"name": "POT 104",
"gardenAssets": [
{
"annotation": "Soil",
"broker": {
"code": "OTHR",
"isOwner": null,
"name": null
},
"datetimeOfArrivalIngarden": 1622571699.767,
"id": "arserana",
"isSealable": true,
"load": null,
"mastergardenCode": null,
"name": null,
"owner": {
"code": "WTR",
"isOwner": null,
"name": null
}
}
]
},
{
"auditOrder": "111",
"code": "POT 111",
"name": "POT 111",
"type": "ProcessingLocation",
"gardenAssets": [
{
"annotation": null,
"broker": {
"code": "CLD",
"isOwner": null,
"name": null
},
"datetimeOfArrivalIngarden": 1622746446.932,
"id": "Bacrea",
"isSealable": true,
"load": null,
"mastergardenCode": null,
"name": null,
"owner": {
"code": "ICE",
"isOwner": null,
"name": null
},
"status": "EMPTY",
"type": "JUNK",
"unavailable": false,
"visitId": "1003768526"
}
]
}
],
"logingarden": true,
"mastergardenCodes": [],
"gardenCode": "FUN5"
}
],
"offsitegardens": [],
"gardenAssetsInTransit": []}
Code:
Option Explicit
Dim S as Object, k, Ks as Object
Set S = CreateObject("ScriptControl")
S.Language = "JScript"
S.addcode "function k(a){var k=[];for(var b in a){k.push('[\'' + b + '\']');}return k;}"
S.Eval ("var J = " & http.ResponseText)
S.Eval ("var L = J.locationsSummaries['0'].locations")
Set Ks = S.Eval("J.locationsSummaries['0'].locations")
For Each K In Ks
If Not IsNull(S.Eval(K.gardenAssets)) = True Then
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1) = "Assets"
End If
Next K
I need to pull different information out of the JSON depending on if there are any gardenAssets. But I can't seem to check to see if the array is empty or not.
You can use the length property in JScript.
Dim S As Object
Dim n As Integer, i As Integer, r As Long
r = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1).Row
Set S = CreateObject("ScriptControl")
With S
.Language = "JScript"
.eval "var J = " & http.ResponseText
.eval "var A = J.locationsSummaries['0'].locations"
For n = 1 To S.eval("A.length")
.eval "var L = A[" & n - 1 & "]"
For i = 1 To .eval("L.gardenAssets.length")
Sheet1.Cells(r, 1) = .eval("L.code")
Sheet1.Cells(r, 2) = .eval("L.gardenAssets[" & i - 1 & "].id")
r = r + 1
Next
Next
End With
The example JSON isn't valid. The last member of an object or the last element of an array shouldn't have a comma after it. So where you have:
"broker": {
"code": "TMTO",
"isOwner": null,
"name": null,
}
There shouldn't be a comma after "name": null - there are multiple other errors like this in the example JSON.
You can use an online JSON validator (like this one) to detect these errors. You would ideally want to fix the system that is generating this invalid JSON rather than trying to correct the issues yourself during processing

Ruby API call to get data from complex json

I'm making an API GET call using Ruby - the call is made to a Learning Management System and returns the following JSON:
{
"id": 12345,
"body": null,
"url": null,
"grade": "75",
"score": 75,
"submitted_at": "2020-05-02T11:30:53Z",
"assignment_id": 9876,
"user_id": 1111,
"submission_type": "online_upload",
"workflow_state": "graded",
"grade_matches_current_submission": true,
"graded_at": "2017-06-05T08:47:49Z",
"grader_id": 2222,
"attempt": 1,
"cached_due_date": "2020-05-03T15:00:00Z",
"excused": false,
"late_policy_status": null,
"points_deducted": null,
"grading_period_id": null,
"late": false,
"missing": false,
"seconds_late": 0,
"entered_grade": "75",
"entered_score": 75,
"preview_url": "https://etcetc",
"turnitin_data": {
"attachment_33333": {
"status": "scored",
"object_id": "44444444",
"similarity_score": 0,
"web_overlap": 0,
"publication_overlap": 0,
"student_overlap": 0,
"state": "none"
}
},
"attachments": [
{
"id": 33333,
"uuid": "kjsdkjhsdfkhsfd",
"folder_id": 55555,
"display_name": "Submission.pdf",
"filename": "Submission.pdf",
"content-type": "application/pdf",
"url": "https://etcetc",
"size": 2668226,
"created_at": "2020-05-02T11:30:51Z",
"updated_at": "2020-06-06T15:01:46Z",
"unlock_at": null,
"locked": false,
"hidden": false,
"lock_at": null,
"hidden_for_user": false,
"thumbnail_url": null,
"modified_at": "2020-05-02T11:30:51Z",
"mime_class": "pdf",
"media_entry_id": null,
"locked_for_user": false,
"preview_url": "api/etcetc"
}
],
"submission_comments": [
{
"id": 99999,
"comment": "here’s a comment",
"author_id": 1,
"author_name": "Mickey Mouse",
"created_at": "2020-05-15T12:54:08Z",
"edited_at": null,
"avatar_path": "/images/users/1",
"author": {
"id": 1,
"display_name": " Mickey Mouse ",
"avatar_image_url": "https://etcetc",
"html_url": "https://etcetc"
}
},
{
"id": 223344,
"comment": "another comment",
"author_id": 2,
"author_name": "Donald Duck",
"created_at": "2020-06-05T10:48:51Z",
"edited_at": null,
"avatar_path": "/images/users/2",
"author": {
"id": 2,
"display_name": "Donald Duck",
"avatar_image_url": "https://etcetc",
"html_url": "https://etcetc"
}
}
]
}
I need to be able to retrieve specific values from "submission_comments", namely the values for "comment", "author_id" and "author_name". At the moment the best I can do is retrieve "submission_comments" as one big entity. Here's how I'm getting that far:
require 'typhoeus'
require 'link_header'
require 'json'
require 'csv'
the_url = 'https://etctetc'
token = 'mytoken'
api_endpoint = '/api/etc'
output_csv = 'C:\Users\me\Desktop\Ruby Canvas course\assignment_comments.csv'
CSV.open(output_csv, 'wb') do |csv|
csv << ["user_id", "TII", "marker"]
end
request_url = "#{the_url}#{api_endpoint}"
count = 0
more_data = true
while more_data
get_comments = Typhoeus::Request.new(
request_url,
method: :get,
headers: { authorization: "Bearer #{token}" }
)
get_comments.on_complete do |response|
#get next link
links = LinkHeader.parse(response.headers['link']).links
next_link = links.find { |link| link['rel'] == 'next' }
request_url = next_link.href if next_link
if next_link && "#{response.body}" != "[]"
more_data = true
else
more_data = false
end
if response.code == 200
data = JSON.parse(response.body)
data.each do |comments|
CSV.open(output_csv, 'a') do |csv|
csv << [comments['id'], comments['turnitin_data'], comments['submission_comments']]
end
end
else
puts "Something went wrong! Response code was #{response.code}"
end
end
get_comments.run
end
puts "Script done running"
I'm new to this (the ruby code is based on an exercise so I may not fully understand it)- any help/advice would be really appreciated!
EDIT: I should also note that this isn't the total JSON response I'm dealing with - this is just one of ten items that are returned
"submission_comments": [
{
"id": 99999,
}
]
the [] means it is array. {} means it is an object.
So you probably need to do something like this:
json["submission_comments"].first["id"]
or better iterate through it:
ids = json["submission_comments"].map{|comment| comment["id"]}
I'm able to get the variables you need if you can read the JSON file in as text, then use Ruby's JSON.parse(...) method on it. I think the main problem is that JSON uses null but Ruby hashes use nil. You could do a string replace or try something like this (I did not modify your JSON, only put it into a single quoted string):
json_text = '{
"id": 12345,
"body": null,
"url": null,
"grade": "75",
"score": 75,
"submitted_at": "2020-05-02T11:30:53Z",
"assignment_id": 9876,
"user_id": 1111,
"submission_type": "online_upload",
"workflow_state": "graded",
"grade_matches_current_submission": true,
"graded_at": "2017-06-05T08:47:49Z",
"grader_id": 2222,
"attempt": 1,
"cached_due_date": "2020-05-03T15:00:00Z",
"excused": false,
"late_policy_status": null,
"points_deducted": null,
"grading_period_id": null,
"late": false,
"missing": false,
"seconds_late": 0,
"entered_grade": "75",
"entered_score": 75,
"preview_url": "https://etcetc",
"turnitin_data": {
"attachment_33333": {
"status": "scored",
"object_id": "44444444",
"similarity_score": 0,
"web_overlap": 0,
"publication_overlap": 0,
"student_overlap": 0,
"state": "none"
}
},
"attachments": [
{
"id": 33333,
"uuid": "kjsdkjhsdfkhsfd",
"folder_id": 55555,
"display_name": "Submission.pdf",
"filename": "Submission.pdf",
"content-type": "application/pdf",
"url": "https://etcetc",
"size": 2668226,
"created_at": "2020-05-02T11:30:51Z",
"updated_at": "2020-06-06T15:01:46Z",
"unlock_at": null,
"locked": false,
"hidden": false,
"lock_at": null,
"hidden_for_user": false,
"thumbnail_url": null,
"modified_at": "2020-05-02T11:30:51Z",
"mime_class": "pdf",
"media_entry_id": null,
"locked_for_user": false,
"preview_url": "api/etcetc"
}
],
"submission_comments": [
{
"id": 99999,
"comment": "here’s a comment",
"author_id": 1,
"author_name": "Mickey Mouse",
"created_at": "2020-05-15T12:54:08Z",
"edited_at": null,
"avatar_path": "/images/users/1",
"author": {
"id": 1,
"display_name": " Mickey Mouse ",
"avatar_image_url": "https://etcetc",
"html_url": "https://etcetc"
}
},
{
"id": 223344,
"comment": "another comment",
"author_id": 2,
"author_name": "Donald Duck",
"created_at": "2020-06-05T10:48:51Z",
"edited_at": null,
"avatar_path": "/images/users/2",
"author": {
"id": 2,
"display_name": "Donald Duck",
"avatar_image_url": "https://etcetc",
"html_url": "https://etcetc"
}
}
]
}'
Part I added:
ruby_hash = JSON.parse(json_text)
submission_comments = ruby_hash["submission_comments"]
submission_comments.each do |submission_comment|
comment = submission_comment["comment"]
author_id = submission_comment["author_id"]
author_name = submission_comment["author_name"]
puts "Comment: #{comment}, Author ID: #{author_id}, Author Name: #{author_name}\n\n"
end
Terminal Result:
=> Comment: here’s a comment, Author ID: 1, Author Name: Mickey Mouse
=> Comment: another comment, Author ID: 2, Author Name: Donald Duck
Edit: I added a jenky af one-liner version just for fun (presuming the json_text variable above is already initialized)
JSON.parse(json_text)["submission_comments"]
.map{|txt| puts(["comment","author_id","author_name"]
.map{|k| k.instance_eval{"#{upcase}: #{txt[to_s]}"}}.join(', '))}
COMMENT: here’s a comment, AUTHOR_ID: 1, AUTHOR_NAME: Mickey Mouse
COMMENT: another comment, AUTHOR_ID: 2, AUTHOR_NAME: Donald Duck

parse json output for primary and secondary hosts from replSetGetStatus

I've used pymongo to connect to mongo replica set and print the status of replica set using json dump. I want to parse this output and display "name" and "stateStr" into a list or array for the user to be able to pick a particular host.Here is my json dump output:
{
{
"replSetGetStatus": {
"date": "2016-10-07T14:21:25",
"members": [
{
"_id": 0,
"health": 1.0,
"name": "xxxxxxxxxxx:27017",
"optime": null,
"optimeDate": "2016-10-07T13:50:11",
"self": true,
"state": 1,
"stateStr": "PRIMARY",
"uptime": 32521
},
{
"_id": 1,
"health": 1.0,
"lastHeartbeat": "2016-10-07T14:21:24",
"lastHeartbeatRecv": "2016-10-07T14:21:24",
"name": "xxxxxxxxxxxx:27017",
"optime": null,
"optimeDate": "2016-10-07T13:50:11",
"pingMs": 0,
"state": 2,
"stateStr": "SECONDARY",
"syncingTo": "xxxxxxxxxxxx:27017",
"uptime": 27297
},
{
"_id": 2,
"health": 1.0,
"lastHeartbeat": "2016-10-07T14:21:24",
"lastHeartbeatRecv": "2016-10-07T14:21:24",
"name": "xxxxxxxxxxxxx:27020",
"pingMs": 0,
"state": 7,
"stateStr": "ARBITER",
"uptime": 32517
}
],
"myState": 1,
"ok": 1.0,
"set": "replica1"
}
}
Please try below Javascript code. It worked for me.
use admin;
var result = rs.status();
var length = result.members.length;
for (var i=0;i<length;i++){
print ("Server Name-" +result.members[i].name);
print ("Server State-" +result.members[i].stateStr);
}

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 );