Append data to a nested list (sublist) in arangodb - list

I apologise if this is a dumb question but it is driving me nuts. I am fairly new to arango but usually I can muddle through and work it out, but not this time.
I want to insert another set of items into the list called 'type' in the data below. I can modify the contents of the sublist using an update but can't seem to work out how to append to the list.
FOR doc IN MAG_TEST
filter doc._key == "3704086"
INSERT {"Name":"Mary","datestart":"16 March 2017"} INTO doc.type
So this
[
{
"_key": "3704086",
"_id": "MAG_TEST/3704086",
"_rev": "3704109",
"name": "Flip",
"type": [
{
"name": "flop",
"sdate": "13 April 2016"
},
{
"name": "flap",
"sdate": "14 April 2017"
}
]
}
]
becomes this
[
{
"_key": "3704086",
"_id": "MAG_TEST/3704086",
"_rev": "3704109",
"name": "Flip",
"type": [
{
"name": "flop",
"sdate": "13 April 2016"
},
{
"name": "flap",
"sdate": "14 April 2017"
},
{
"name": "fling",
"sdate": "18 April 2018"
}
]
}
]

Here is an example of how you can use UPDATE with APPEND to update an attribute which contains an array of objects:
FOR doc IN MAG_TEST
FILTER doc._key == "3704086"
UPDATE doc WITH { type: APPEND(doc.type, {"Name":"Mary","datestart":"16 March 2017"})} IN MAG_TEST
In this example you:
FILTER to find the document you want to update
UPDATE the found document
Use WITH to show which attributes you want to update
Identify the type attribute as being updated
Use APPEND to add a new object to the existing value of doc.type
Specify the collection the updated document will be stored in, MAG_TEST
Hope that helps.
Documentation on the UPDATE command
Documentation on Array functions
Note: Don't use MERGE as I mentioned above, MERGE is used to merge the attributes of two documents into a single document. For joining arrays, APPEND is an option you can use. Going through the other Array Functions can help solve use cases you're sure to have when manipulating and fetching data from arrays.

Related

how to get facebook page creation date using facebook api

my try : https://graph.facebook.com/v12.0/{mypageid}?fields={fieldname_of_type_PageStartDate}
Could not get any response when using this api and i am also confused about {fieldname_of_type_PageStartDate} parameter value. i tried day,month,year value according to https://developers.facebook.com/docs/graph-api/reference/page-start-date/ this fb website but it didn't work.
please suggest any way to get facenook page creation date using api.
The documentation is a bit misleading, because what that page does not tell you on its own, is that those fields are part of the start_info property of the page - so you have to query that one.
https://graph.facebook.com/v12.0/pageid?fields=start_info
This will give you a structure of the following format:
"data": [
{
"name": "...",
"start_info": {
"type": "Started",
"date": {
"year": 2021,
"month": 11,
"day": 29
}
},
"id": "1234567890"
},
Not all sub-fields will always be set; you might for example encounter types Founded with only a year set, or Unspecified with no date info at all.
Note that this is not the actual page creation date; but the "start date" of the entity represented by the page. So it must be explicitly set in the page settings, otherwise this field will be empty.

CouchDB Map syntax

I have documents in CouchDB (v. 2.1.1) as follows:
{
"xyz": "a",
"abc": "def"
},
{
"xyz": "a",
"ghi": "jkl"
},
{
"xyz": "a",
"mno": "pqr"
},
{
"xyz": "a",
"stu": "vwx"
},
{
"xyz": "a",
"bcd": 1000
}
If I run a simple map function, for example:
function (doc) {
if (doc.xyz ){
emit(doc.xyz, doc.abc);}}
I get:
{
"id": "4c3406a1d92942b4fb10d1314e0061a9",
"key": "a",
"value": "def"
},
{
"id": "4c3406a1d92942b4fb10d1314e006ccf",
"key": "a",
"value": null
},
{
"id": "4c3406a1d92942b4fb10d1314e00787f",
"key": "a",
"value": null
},
{
"id": "4c3406a1d92942b4fb10d1314e00871e",
"key": "a",
"value": null
},
{
"id": "4c3406a1d92942b4fb10d1314e00906a",
"key": "a",
"value": null
}
I want to try and eliminate the 'null' outputs.
I am looking at having a CouchDB database with many small documents containing small snippets of information rather than having larger documents containing much more information per document.
My question is, is my document design a good one and if so how do I get just what I am looking for rather than rows of 'nulls'. If my storage design is not ideal, what kind of design should I be looking at to simplify the output given my plan to have many small 'docs'.
EDIT:
Having looked at possible answers, I have decided that having numerous small documents as I described in my question is not giving me the kind of benefit I imangined they would.
I was unable to get a satisfactory solution to the map function to get readable answers.
However, I investigated the 'Mango' query system available in recent updates of CouchDB and I was able using these queries to get acceptable output from a database like my supplied one.
This is what I did:
curl -X POST http://admin:123#127.0.0.1:5984/ptn/_find -d '{"selector": {"$or": [{"abc": {"$gt": null}},{"ghi": {"$gt": null}}]},"fields": ["abc","ghi"]}' -H "Content-Type:application/json"
Un-minified:
{
"selector": {
"$or": [
{
"abc": {
"$gt": null
}
},
{
"ghi": {
"$gt": null
}
}
]
},
"fields": [
"abc",
"ghi"
]
}
The output:
{"docs":[
{"abc":"def"},
{"ghi":"jkl"}
]
.....
A concise answer.
Sorting can be done but sorted fields must be indexed. Indexing is in any case advised for larger data sets.
Reference:
http://docs.couchdb.org/en/2.1.1/api/database/find.html
As my question required a map function, this perhaps cannot be regarded as a valid answer but for me it is an answer. I have tried the 'Mango' query system a little on other databases and it seems to be more useful/powerful than I thought is was although it offers no means of totaling etc.

FB Graph API - Filtering results by specific IDs?

I am making a request to a specific node and edge using the graph API:
https://graph.facebook.com/v2.6/NODE_ID/EDGE_NAME
Example:
https://graph.facebook.com/v2.6/00000000000000/reports
which returns the results below:
"data": [
{
"id": "111111111111111",
"name": "Report A"
},
{
"id": "22222222222222",
"name": "Report B"
},
{
"id": "33333333333333",
"name": "Report C"
}
]
The above is literally returning a list of reports by id/name that exist under a specific company.
If I want to filter the results by specific reports, how can I go about doing this?
I tried variations such as the below, but they haven't worked and still return all reports:
https://graph.facebook.com/v2.6/00000000000000/reports?ids=22222222222222
I know I can make the report ID as the node to access it directly:
https://graph.facebook.com/v2.6/22222222222222/
But I want to view the properties of a subset of reports that belong to the company, so I was thinking I could build an array to do this.
https://graph.facebook.com/v2.6/00000000000000/reports?ids=22222222222222,33333333333333
Expected Result:
"data": [
{
"id": "111111111111111",
"name": "Report A"
},
{
"id": "22222222222222",
"name": "Report B"
},
{
"id": "33333333333333",
"name": "Report C"
}
]
This seems like it should work based on the below documentation, but it does not...
https://developers.facebook.com/docs/graph-api/using-graph-api
Could it be because the edge I'm accessing isn't able to recognize these IDs for some reason...? I know it's hard to say without knowing what I'm doing, but I can't disclose fully as it's proprietary...
Any advice is appreciated.

Fetching With Distinct/Unique Values

I have a Cloudant database with objects that use the following format:
{
"_id": "0ea1ac7d5ef28860abc7030444515c4c",
"_rev": "1-362058dda0b8680a818b38e9c68c5389",
"text": "text-data",
"time-data": "1452988105",
"time-text": "3:48 PM - 16 Jan 2016",
"link": "http://url/to/website"
}
I want to fetch objects where the text attribute is distinct. There will be objects with duplicate text and I want Cloudant to handle removing them from a query.
How do I go about creating a MapReduce view that will do this for me? I'm completely new to MapReduce and I'm having difficulty understanding the relationship between the map and reduce functions. I tried tinkering with the built-in COUNT function and writing my own view, but they've failed catastrophically, haha.
Anyways, would it be easier to just delete the duplicates? If so, how do I do that?
While I'm trying to study this and find ELI5s, would anyone help me out? Thanks in advance! I appreciate it.
I'm not sure a MapReduce view is what you are looking for. A MapReduce view will essentially allow you to get the text and the number of docs with that same text, but you really won't be able to get the rest of the fields in the doc (because MapReduce has no idea which doc to return when multiple docs match the text). Here is a sample MapReduce view:
{
"_id": "_design/textObjects",
"views": {
"by_text": {
"map": "function (doc) { if (doc.text) { emit(doc.text, 1); }}",
"reduce": "_count"
}
},
"language": "javascript"
}
What this is doing:
The Map part of the Map Reduce takes each doc and maps it into a doc that looks like this:
{"key":"text-data", "value":1}
So, if you had 7 docs, 2 where text="text-data" and 5 where text="other-text-data" the data would look like this:
{"key":"text-data", "value":1}
{"key":"text-data", "value":1}
{"key":"other-text-data", "value":1}
{"key":"other-text-data", "value":1}
{"key":"other-text-data", "value":1}
{"key":"other-text-data", "value":1}
{"key":"other-text-data", "value":1}
The reduce part of the MapReduce ("reduce": "_count") groups the docs above by the key and returns the count:
{"key":"text-data","value":2},
{"key":"other-text-data","value":5}
You can query this view on your Cloudant instance:
https://<yourcloudantinstance>/<databasename>
/_design/textObjects
/_view/by_text?group=true
This will result in something similar to the following:
{"rows":[
{"key":"text-data","value":2},
{"key":"other-text-data","value":5}
]}
If this is not what you are looking for, but rather you are just looking to keep the latest info for a specific text value then you can simply find an existing document that matches that text and update it with new values:
Add an index on text:
{
"index": {
"fields": [
"text"
]
},
"type": "json"
}
Whenever you add a new document find the document with that same exact text:
{
"selector": {
"text": "text-value"
},
"fields": [
"_id",
"text"
]
}
If it exists update it. If not then insert a new document.
Finally, if you want to keep multiple docs with the same text value, but just want to be able to query the latest you could do something like this:
Add a property called latest or similar to your docs.
Add an index on text and latest:
{
"index": {
"fields": [
"text",
"latest"
]
},
"type": "json"
}
Whenever you add a new document find the document with that same exact text where latest == true:
{
"selector": {
"text": "text-value",
"latest" : true
},
"fields": [
"_id",
"text",
"latest"
]
}
Set latest = false on the existing document (if one exists)
Insert the new document with latest = true
This query will find the latest doc for all text values:
{
"selector": {
"text": {"$gt":null}
"latest" : true
},
"fields": [
"_id",
"text",
"latest"
]
}

How do I use JSON with U2/Universe

U2/Universe JSON document have the following UDOSetProperty, how would one set the value if it has multiple values? For example if I have multiple emails.
example: UDOSetProperty(udoHandle, "to", value)
"to": [
{
"email": "recipientEmail#example.com",
"name": "Recipient Name",
"type": "to"
}
],
Not sure if you are trying to add another "to" array element or if you want to add a 2nd "email" only.
So working with your example:
"to": [
{
"email": [ "recipientEmail#example.com",
"name": "Recipient Name",
"type": "to"
},
{
"email": [ "recipient2Email#example.com",
"name": "Recipient2 Name",
"type": "to"
}
],
If you wanted to create the above JSON from scratch, with the UDO commands, the steps would be:
Using the following functions should help you with what you are trying to do:
Create the initial/root object UDOCreate(UDO_OBJECT,
udoHandle)
Create the array UDOCreate(UDO_ARRAY,
thisArray)
( Use UDOCreate and UDOSetProperty to create the theEmailObject you
want to add to the array, and then add it to the object with
UDOArrayAppendItem( thisArray, theEmailObject )
Then add the array to the root object eith UDOSetProperty(udoHandle,
"TO", thisArray)
Note the part that is important is that there are several functions for dealing with arrays.
Mike
Created a program that builds the JSON with the U2 UDO functions, and added it to github:
https://github.com/RocketSoftware/multivalue-lab/blob/master/U2/Demos/UDO/JSON/The-Basics/arrayExample