Related
I am struggling to get my head around MongoDB and aggregates and groups. I've spent about 3 days so far.
I have source data that looks like...
{
"formName" : "my form",
"updatedAt" : "2021-11-02T13:29:00.123Z",
},
{
"formName" : "another form",
"lastUpdated" : "2021-10-01T13:29:00.123123",
},
Note that there are potentially different date names, though these are the only differences.
I am attempting to achieve an output of...
{
"_id": null,
"text": "my form", (NOTE: This is the formName)
"children": [{
"text" : 2021, (This is the year part of the updated)
"children" : [
{"text" : 1}, (These are the month part of the updated)
{"text" : 2},
{"text" : 3},
{"text" : 4}
]
},
]
}
So, basically a tree, which has formName, with child branch of years, with child branch of months.
I have tried all kinds of things, many don't work, such as nested $addToSet inside $groups.
I have been close, but I can't solve it.
This is the closest, but this doesn't work.
db.FormsStore.aggregate( [
{$match:{myKey:"a guid to group my forms together"}},
{$project: {formName:1, lastUpdated:1, updatedAt:1}},
{
$group: {
_id: { formName: "$formName" },
Year: {$addToSet: {$year: {$dateFromString: { dateString: "$lastUpdated" }}}},
Month: {$addToSet: {$month: {$dateFromString: { dateString: "$lastUpdated" }}}},
}
},
{
$group: {
_id: { formName: "$_id.formName" },
Time: {$addToSet: {year: "$Year", month: "$Month"}}
}
}
]
)
The output from that is showing...
{
_id: { formName: 'One of my forms' },
Time: [
{
year: [ 2021 ],
month: [ 10, 11 ]
}
]
}
This will all be used in C#
Your help would be greatly appreciated.
Query
adds a new field "date" with the date on Date format
group first the more specific (formname+year) to put the months in the array
group then the less specific (formname) to put the years in the array
aggregate(
[{"$set":
{"date":
{"$cond":
["$updatedAt", {"$dateFromString": {"dateString": "$updatedAt"}},
{"$dateFromString": {"dateString": "$lastUpdated"}}]},
"updatedAt": "$$REMOVE",
"lastUpdated": "$$REMOVE"}},
{"$group":
{"_id": {"text": "$formName", "year": {"$year": "$date"}},
"children": {"$push": {"text": {"$month": "$date"}}}}},
{"$group":
{"_id": "$_id.text",
"children":
{"$push": {"text": "$_id.year", "children": "$children"}}}},
{"$set": {"text": "$_id", "_id": "$$REMOVE"}}])
Edit
The bellow sorts also by year/month, and keeps only unique year/months per formName.
the difference is the group by formName,year,month to take the unique (first aacumulator will take one only of those that have the same in all 3)
replace-root (make that first document ROOT document)
and then sort by those 3 fields (descending year,ascending month)
group
sort by 2 fields
final group
PlayMongo
*mongoplaygroung loses the order of fields, run it on your driver also to be sure
aggregate(
[{"$set":
{"date":
{"$cond":
["$updatedAt", {"$dateFromString": {"dateString": "$updatedAt"}},
{"$dateFromString": {"dateString": "$lastUpdated"}}]},
"updatedAt": "$$REMOVE",
"lastUpdated": "$$REMOVE"}},
{"$set": {"year": {"$year": "$date"}, "month": {"$month": "$date"}}},
{"$group":
{"_id": {"formName": "$formName", "year": "$year", "month": "$month"},
"doc": {"$first": "$$ROOT"}}},
{"$replaceRoot": {"newRoot": "$doc"}},
{"$sort": {"formName": 1, "year": -1, "month": 1}},
{"$group":
{"_id": {"text": "$formName", "year": "$year"},
"children": {"$push": {"text": "$month"}}}},
{"$sort": {"_id.text": 1, "_id.year": -1}},
{"$group":
{"_id": "$_id.text",
"children":
{"$push": {"text": "$_id.year", "children": "$children"}}}},
{"$set": {"text": "$_id", "_id": "$$REMOVE"}}])
With data
[
{
"formName": "my form",
"updatedAt": "2021-11-02T23:30:15.123Z"
},
{
"formName": "my form",
"updatedAt": "2021-10-02T23:30:15.123Z"
},
{
"formName": "my form",
"updatedAt": "2020-06-02T23:30:15.123Z"
},
{
"formName": "my form",
"updatedAt": "2020-07-02T23:30:15.123Z"
},
{
"formName": "another form",
"updatedAt": "2021-10-01T23:30:15.123Z"
},
{
"formName": "another form",
"updatedAt": "2021-10-01T23:30:15.123Z"
},
{
"formName": "another form",
"updatedAt": "2021-09-01T23:30:15.123Z"
},
{
"formName": "another form",
"updatedAt": "2021-08-01T23:30:15.123Z"
},
{
"formName": "another form",
"updatedAt": "2020-10-01T23:30:15.123Z"
}
]
I got results
[{
"children": [
{
"text": 2021,
"children": [
{
"text": 10
},
{
"text": 11
}
]
},
{
"text": 2020,
"children": [
{
"text": 6
},
{
"text": 7
}
]
}
],
"text": "my form"
},
{
"children": [
{
"text": 2021,
"children": [
{
"text": 8
},
{
"text": 9
},
{
"text": 10
}
]
},
{
"text": 2020,
"children": [
{
"text": 10
}
]
}
],
"text": "another form"
}]
I continued to work on it, and while this is also not quite right (yet), here is what I came up with.
db.FormsStore.aggregate([
{$project: {formName:1, lastUpdated:1, updatedAt:1}},
{
$group: {
_id: {formName: "$formName", Year: {$year: {$dateFromString: { dateString: "$updatedAt" }}}, Month: {$month: {$dateFromString: { dateString: "$updatedAt" }}}},
}
},
{
$group: {
_id: {formName: "$_id.formName", Year: "$_id.Year"},
Months: {$addToSet: {Text: "$_id.Month"}}
}
},
{
$group: {
_id: "$_id.formName", Children: {$addToSet: {Text: "$_id.Year", Children: "$Months"}},
}
}
])
Getting all my data in the first group, then creating a set with the months in the second group, then creating a set with the years and adding the months to each year in the third group.
I have used sys-date entity to identify the date from users input. But the watson assistant sys-date entity doesn't identify some user inputs correctly.
For example: "next year march" is identified as 2020-01-01.
But if the user input is as "march next year" date is identified as 2020-03-01.
{
"entity": "sys-date",
"location": [
0,
9
],
"value": "2020-01-01",
"confidence": 1,
"metadata": {
"calendar_type": "GREGORIAN",
"timezone": "GMT"
}
},
{
"entity": "sys-date",
"location": [
0,
9
],
"value": "2020-12-31",
"confidence": 1,
"metadata": {
"calendar_type": "GREGORIAN",
"timezone": "GMT"
}
},
{
"entity": "sys-date",
"location": [
10,
15
],
"value": "2020-03-01",
"confidence": 1,
"metadata": {
"calendar_type": "GREGORIAN",
"timezone": "GMT"
}
},
{
"entity": "sys-date",
"location": [
10,
15
],
"value": "2020-03-31",
"confidence": 1,
"metadata": {
"calendar_type": "GREGORIAN",
"timezone": "GMT"
}
}
This is the entity identification for the input "next year march"
I am using UPS Rates API ( JSON based with option Shoptimeintransit) to get available delivery dates for supplied shipment date.
https://www.ups.com/upsdeveloperkit/downloadresource?loc=en_CA
In DeliveryTimeInformation, I am setting pickup info.
{
"Security": {
"UsernameToken": {
"Username": "xxxxxxx",
"Password": "xxxxxxx"
},
"UPSServiceAccessToken": {
"AccessLicenseNumber": "xxxxxxxxxxx"
}
},
"RateRequest": {
"Request": {
"RequestOption": "Shoptimeintransit",
"TransactionReference": {
"CustomerContext": "Your Customer Context"
}
},
"CustomerClassification": {
"Code": "00"
},
"PickupType": {
"Code": "06"
},
"Shipment": {
"DeliveryTimeInformation": {
"PackageBillType": "07",
"Pickup": {
"Date": "20170925",
"Time": "1140"
}
},
"Shipper": {
"ShipperNumber": "xxxxxxx",
"Address": {
"City": "Kansas City",
"StateProvinceCode": "MO",
"CountryCode": "US",
"PostalCode": "xxxx"
}
},
"ShipTo": {
"Address": {
"City": "Redwood",
"StateProvinceCode": "CA",
"CountryCode": "US",
"PostalCode": "xxxx"
}
},
"ShipFrom": {
"Address": {
"City": "Kansas City",
"StateProvinceCode": "MO",
"CountryCode": "US",
"PostalCode": "xxxx"
}
},
"Package": {
"PackagingType": {
"Code": "02"
},
"Dimensions": {
"UnitOfMeasurement": {
"Code": "IN"
},
"Length": "5",
"Width": "4",
"Height": "3"
},
"PackageWeight": {
"UnitOfMeasurement": {
"Code": "LBS"
},
"Weight": "1"
}
},
"NumOfPieces": "3",
"ShipmentRatingOptions": {
"NegotiatedRatesIndicator": ""
}
}
}
}
Question is, I need available delivery dates for next N shipment dates, but API only takes single shipment date in DeliveryTimeInformation > Pickup section.
So, one possibility is to call API N times and combine results, which doesn't seems a good idea.
Anyone knows any related API that use to take pickup dates as list and return all possible delivery dates,service codes for supplied data.
The Docs state Max Allowed: 1 for DeliveryTimeInformation, so no.
You can request it for the next API update (each January and July) through customer service, but you'll have to make N requests 'till then.
I am using QuickBooks Online Plus, which means i can edit the item. I would like to use the API to change the on hand # for an item. I've created an item "test1" through QuickBooks Online Plus. When i read the item from API i got the following in the attached json file. things looks great as follow:
{
"QueryResponse": {
"Item": [
{
"Name": "test1",
"Active": true,
"FullyQualifiedName": "test1",
"Taxable": false,
"UnitPrice": 3,
"Type": "Inventory",
"IncomeAccountRef": {
"value": "60",
"name": "Sales of Product Income"
},
"PurchaseCost": 1,
"ExpenseAccountRef": {
"value": "61",
"name": "Cost of Goods Sold"
},
"AssetAccountRef": {
"value": "62",
"name": "Inventory Asset"
},
"TrackQtyOnHand": true,
"QtyOnHand": 6,
"InvStartDate": "2015-12-02",
"domain": "QBO",
"sparse": false,
"Id": "19",
"SyncToken": "1",
"MetaData": {
"CreateTime": "2015-12-01T14:38:23-08:00",
"LastUpdatedTime": "2015-12-01T14:38:42-08:00"
}
}
],
"startPosition": 1,
"maxResults": 1
},
"time": "2015-12-02T09:59:29.936-08:00"
}
But when i tried to update that item using the json object below:
{
"Name": "test1",
"Active": true,
"Taxable": false,
"UnitPrice": 3,
"Type": "Inventory",
"IncomeAccountRef": {
"value": "60",
"name": "Sales of Product Income"
},
"PurchaseCost": 1,
"ExpenseAccountRef": {
"value": "61",
"name": "Cost of Goods Sold"
},
"AssetAccountRef": {
"value": "62",
"name": "Inventory Asset"
},
"TrackQtyOnHand": true,
"QtyOnHand": 16,
"InvStartDate": "2015-12-02",
"domain": "QBO",
"sparse": false,
"Id": "19",
"SyncToken": "2"
}
, i got an error like this:
{"Fault":{"Error":[{"Message":"Stale Object Error","Detail":"Stale Object Error : You and seven.li#hotschedules.com were working on this at the same time. seven.li#hotschedules.com finished before you did, so your work was not saved.","code":"5010","element":""}],"type":"ValidationFault"},"time":"2015-12-02T10:42:52.466-08:00"}
I would like to update the on hand quantity. Does anyone know what's wrong and how to do it? Thanks.
The problem is with the "SyncToken". I believe when you try to update the new item, you should not increment the "SyncToken", you should keep it the same. QBO will update the "SyncToken" for you.
I guess this is a big ask. Using PHP I grab this Facebook Graph API json feed json feed link
{
"data": [
{
"id": "10369058551_10150645263758552",
"from": {
"name": "Land Rover",
"category": "Cars",
"id": "10369058551"
},
"message": "This week's Land Rover photo of the week is by Rodrigo Beja. Don't forget to submit your best photos each week to get featured.",
"link": "http://www.facebook.com/photo.php?fbid=10150645263678552&set=a.443106273551.221975.10369058551&type=1",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yz/r/StEh3RhPvjk.gif",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/10369058551/posts/10150645263758552"
},
{
"name": "Like",
"link": "http://www.facebook.com/10369058551/posts/10150645263758552"
}
],
"privacy": {
"description": "United Kingdom",
"value": "CUSTOM"
},
"type": "photo",
"object_id": "10150645263678552",
"created_time": "2012-02-03T17:19:03+0000",
"updated_time": "2012-02-03T22:32:28+0000",
"likes": {
"data": [
{
"name": "Mandy Elder",
"id": "100000250758731"
}
],
"count": 85
},
"comments": {
"data": [
{
"id": "10369058551_10150645263758552_6835532",
"from": {
"name": "John Sharp",
"id": "652940638"
},
"message": "This photo was used as part of the g4 challenge publicity photo pack around 2005-6 \nI remember because at the time I used it as a profile pic on msn \n\nAwesome photo - sums it up perfectly - I love it!!",
"created_time": "2012-02-03T21:39:48+0000"
},
{
"id": "10369058551_10150645263758552_6835852",
"from": {
"name": "Kathryn Piddington",
"id": "777370532"
},
"message": "Mud is good for the soul :)",
"created_time": "2012-02-03T22:32:28+0000"
}
],
"count": 14
}
},
{
"id": "10369058551_355476307803889",
"from": {
"name": "Land Rover",
"category": "Cars",
"id": "10369058551"
},
"message": "Click below to watch the new Range Rover Sport advert and catch up on the latest Land Rover and Range Rover news in this week\u2019s round-up. ",
"picture": "http://external.ak.fbcdn.net/safe_image.php?d=AQAx7xz602rfhyIn&w=90&h=90&url=http\u00253A\u00252F\u00252Fblog.landrover.com\u00252Fwp-content\u00252Fuploads\u00252F12my_rrs_044_LowRes.jpg",
"link": "http://blog.landrover.com/vehicles/the-land-rover-and-range-rover-weekly-19-3578.html#axzz1lKthI4F1",
"name": "The Land Rover and Range Rover Weekly 19 | Land Rover Blog",
"caption": "blog.landrover.com",
"description": "In this week\u2019s round-up of all things Land Rover and Range Rover, the new Range Rover Sport advert, Which? figures reveal the running costs of the Range Rover Evoque in comparison with competitors and a history of Land Rover narrated by Ranulph Fiennes.",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yD/r/aS8ecmYRys0.gif",
"actions": [
{
"name": "Comment",
"link": "http://www.facebook.com/10369058551/posts/355476307803889"
},
{
"name": "Like",
"link": "http://www.facebook.com/10369058551/posts/355476307803889"
}
],
"privacy": {
"description": "United Kingdom",
"value": "CUSTOM"
},
"type": "link",
"created_time": "2012-02-03T16:44:42+0000",
"updated_time": "2012-02-03T16:44:42+0000",
"likes": {
"data": [
{
"name": "Steve Nesbitt",
"id": "533982936"
}
],
"count": 10
},
"comments": {
"count": 0
}
},
{
"id": "10369058551_10150642499593552",
I'd like to the top level items to a mysql table, then each sub level to anaother table keeping a key / link between each table and then any sub level of a sublevel and linking this too. Is this possible?
I have got as far as this:-
$page = file_get_contents($url);
$json_output = json_decode($page, true);
I can't figure out how to loot hrough each row and add teh data to a Mysql table.
Thanks for your help in advance
Jonathan
Try to loop it as array then make sql query. Each array you put a unique key (for top level item). So, you can use your top level key to sub level foreign key..