How would I write a query to give me the following results? - orientdb

I have 2 classes.
Activities and Comments.
Activities, is linked to comments.
Comments, has the fields username, comment and created_at
When I execute select from Activities, this is an example of my current results. Below, you will see an example of my desired results (Example 2)
Example 1
{
"#type": "d",
"#rid": "#28:38",
"#version": 10,
"#class": "Activities",
"activity_type_id": 1,
"username": "johnt",
"title": "random new activitie test",
"image": "http://www.someurl.com/images/blah-2.png",
"comments": [
"#24:26",
"#24:27",
"#24:28",
"#24:29",
"#24:30",
"#24:31"
],
"Activity_Properties": {
"comment_count": 0,
"share_count": 0,
"like_count": 0
}
}
my desired results are the following
Example 2
{
"#type": "d",
"#rid": "#28:38",
"#version": 10,
"#class": "Activities",
"activity_type_id": 1,
"username": "ultimaterandomuser",
"title": "random new activitie test",
"image": "http://www.someurl.com/images/blah.png",
"comments": [
{
"username": "randomuser1",
"comment": "randomuser1 comment"
"created_at": "2016-06-23 00:00:00",
},
{
"username": "randomuser2",
"comment": "randomuser2 comment"
"created_at": "2016-06-23 00:00:00",
},
{
"username": "randomuser3",
"comment": "randomuser3 comment"
"created_at": "2016-06-23 00:00:00",
}
],
"Activity_Properties": {
"comment_count": 0,
"share_count": 0,
"like_count": 0,
}
}

I tried your case with this simple dataset:
Output Query 1:
SELECT FROM Activities
{
"result": [
{
"#type": "d",
"#rid": "#12:0",
"#version": 1,
"#class": "Activities",
"activity_type_id": 1,
"username": "ultimaterandomuser",
"title": "random new activitie test",
"image": "http://www.someurl.com/images/blah.png",
"comments": [
"#13:0",
"#13:1",
"#13:2"
],
"Activity_Properties": {
"comment_count": 0,
"share_count": 0,
"like_count": 0
},
"#fieldTypes": "comments=n"
}
],
"notification": "Query executed in 0.01 sec. Returned 1 record(s)"
}
Output Query 2:
SELECT expand(#this.exclude('comments')) FROM (SELECT *, $comments as commentsList FROM Activities
LET $comments = (SELECT expand(#this.exclude('#rid')) FROM (SELECT username, comment, created_at FROM Comments WHERE #rid IN $parent.current.comments)))
{
"result": [
{
"#type": "d",
"#rid": "#12:0",
"#version": 1,
"#class": "Activities",
"activity_type_id": 1,
"username": "ultimaterandomuser",
"title": "random new activitie test",
"image": "http://www.someurl.com/images/blah.png",
"Activity_Properties": {
"comment_count": 0,
"share_count": 0,
"like_count": 0
},
"commentsList": [
{
"#type": "d",
"#version": 0,
"username": "randomuser1",
"comment": "randomuser1 comment",
"created_at": "2016-06-25 03:33:13",
"#fieldTypes": "created_at=t"
},
{
"#type": "d",
"#version": 0,
"username": "randomuser2",
"comment": "randomuser2 comment",
"created_at": "2016-06-25 03:33:13",
"#fieldTypes": "created_at=t"
},
{
"#type": "d",
"#version": 0,
"username": "randomuser3",
"comment": "randomuser3 comment",
"created_at": "2016-06-25 03:33:13",
"#fieldTypes": "created_at=t"
}
],
"#fieldTypes": "commentsList=z"
}
],
"notification": "Query executed in 0.041 sec. Returned 1 record(s)"
}
Hope it helps

Related

Paging not working with spring boot and mongodb

I saw several articles here on stackoverflow but I couldn't get my pagination working with mongodb and spring boot. The code always returns only one result when I change the value of the limit or skip variable the result is always nothing.
My Repository:
public interface CategoryProductRepository extends MongoRepository<CategoryProduct, String> {
#Aggregation(pipeline = {
"{ '$match': { 'categories.category_id' : ?0 } }",
"{ '$skip' : ?1 }",
"{ '$limit' : ?2 }"
})
List<CategoryProduct> findCategoriesCategoryId(
Long field0,
Long skip,
Long limit
);
}
My structure:
[
{
"product_id": 4,
"id_colletion": 4,
"product_tite": "Testar",
"product_quant": 50,
"product_slug": "slug6",
"product_active": "ativo",
"product_description": "description",
"product_price_un": 50,
"product_price_kg": 10.25,
"star": 0,
"photos": [
{
"photo": "url",
"type": "mini",
"title": "título",
"active": "ativo"
},
{
"photo": "url 2",
"type": "mini",
"title": "título 2",
"active": "ativo"
}
],
"categories": [
{
"category_id": 1,
"name": "categoria 1",
"active": "ativo"
},
{
"category_id": 2,
"name": "categoria 2",
"active": "ativo"
}
]
},
{
"product_id": 5,
"id_colletion": 5,
"product_tite": "new",
"product_quant": 50,
"product_slug": "slugnew",
"product_active": "ativo",
"product_description": "descriptionnew",
"product_price_un": 50,
"product_price_kg": 10.25,
"star": 0,
"photos": [
{
"photo_id": 13,
"photo": "photo 11",
"type": "mini",
"title": "photo 11",
"active": "ativo"
}
],
"categories": [
{
"category_id": 1,
"name": "categoria 1",
"active": "ativo"
}
]
},
{
"product_id": 9,
"id_colletion": 9,
"product_tite": "2",
"product_quant": 2,
"product_slug": "slugnew2",
"product_active": "ativo",
"product_description": "2",
"product_price_un": 2,
"product_price_kg": 2,
"star": 0,
"photos": [
{
"photo": "photo 2",
"type": "mini",
"title": "photo 2",
"active": "desativo"
}
],
"categories": [
{
"category_id": 2,
"name": "categoria 2",
"active": "ativo"
}
]
}
]
Does anyone have any idea where my mistake is?
[SOLVED]
I was inserting the limit and skip wrong but the code works fine

Extract ? number of JSON array objects into rows

So I am trying to pivot some large Json arrays into a row by row format (postgres db). So imagine
{“searchResults”:[{“id”:“89705”,“score”:42,“title”:“Foo.”,“properties”:{…
Currently the most results we have in an array is about 300~ id's and explicitly saying;
Data::Json->'searchResults'->0->'tags'->0->>'label' as "Tag - Result 1",
...
Data::Json->'searchResults'->300->'tags'->0->>'label' as "Tag - Result
1",
Ideal Output
Array, ID , Score, Title
----
1 89705, 42, foo
1 89706, 34, bar
2 90003, 54, thing
2 98594, 53, that
(so 1,2 represent different rows in the initial table that both contain ??? amounts of objects the JSON data array)
Expanded JSON
{
"searchResults": [
{
"id": "897096",
"score": 42,
"title": "foo.",
"properties": {
"#type": "blah",
},
"publishedDate": "2018-06-30T10:20:20.555040Z",
"comments": [
{
"content": "",
"owner": {
"firstName": "",
"id": 0,
"lastName": ""
},
"id": 0,
"contentType": "",
"documentPk": 0,
"workflowStep": 0,
"order": 0
}
],
"tags": [
{
"tag": 783,
"label": "NO",
"iconClass": "",
"subGroup": "",
"exclude": false
},
{
"tag": 786,
"label": "Different name",
"iconClass": "",
"subGroup": "",
"exclude": false
}
],
"reviewTags": [
{
"tag": 2,
"label": "Accept",
"iconClass": "",
"subGroup": "",
"exclude": false
}
],
"original": {
..."names": [
{
"full_name": "This name"
}
],
"Entry Type": "Organization",
"Last Updated": "2018/05/03",
"Hit Category": "N/A",
"Aliases": [
"Olaj",
"hbhbhb"
]
},
"snippet": "",
"url": "",
"source": "_"
},
{
"id": "879057",
"score": 36,
"title": "name of company",
"properties": {
"#type": "",
"category": "SOE",
"type": "Organization",
"country": "Korea, Republic Of",
"subcategory": ""
},
"publishedDate": "2018-05-31T10:20:20.559714Z",
"comments": [
{
"content": "",
"owner": {
"firstName": "",
"id": 0,
"lastName": ""
},
"id": 0,
"contentType": "",
"documentPk": 0,
"workflowStep": 0,
"order": 0
}
],
"tags": [
{
"tag": 783,
"label": "NO",
"iconClass": "",
"subGroup": "",
"exclude": false
},
{
"tag": 786,
"label": "Different name",
"iconClass": "",
"subGroup": "",
"exclude": false
}
Any advise on what my options are here ?
Thanks #a_horse_with_no_name this worked perfectly.
it's unclear to me how the JSON continues in the array, but it seems you are looking for something like this:
with testdata(props) as (
values (
'{"searchResults":
[
{"id":"89705","score":42,"title":"Foo"},
{"id":"89706","score":34, "title":"bar"}
]}'::jsonb
)
)
select x.idx,
x.val ->> 'id' as id,
x.val ->> 'score' as score,
x.val ->> 'title' as title
from testdata, jsonb_array_elements(props -> 'searchResults') with ordinality as x (val, idx);
returns
idx | id | score | title
----+-------+-------+------
1 | 89705 | 42 | Foo
2 | 89706 | 34 | bar

How to update a part of an array sub document in MongoDB

I have this document in my mongodb collection:
{
"_id": "YLRM9Wi7f6tp6qNbS",
"sessionId": "hLDkkJKR4Muik6tbe",
"userId": "ZYoG4cH8HcCDPMDGr",
"shopId": "J8Bhq3uTtdgwZx3rz",
"workflow": {
"status": "",
"workflow": ["String"]
},
"billing": [Object],
"discount": 0,
"tax": 0,
"items": [
{
"_id": "JwR233jD2c4HKeYKq",
"shopId": "J8Bhq3uTtdgwZx3rz",
"productId": "BCTMZ6HTxFSppJESk",
"quantity": 1,
"product": {
"_id": "BCTMZ6HTxFSppJESk",
"title": "Product",
"shopId": "J8Bhq3uTtdgwZx3rz",
"ancestors": [],
"createdAt": "2018-01-12T10:22:18.853Z",
"description": "",
"handle": "product",
"hashtags": [
"rpjCvTBGjhBi2xdro",
"cseCBSSrJ3t8HQSNP"
],
"price": {
"range": "12.99 - 19.99",
"min": 12.99,
"max": 19.99
},
"isVisible": true,
"isLowQuantity": false,
"isSoldOut": false,
"isBackorder": false,
"metafields": [
{
"key": "Material",
"value": "Cotton"
},
{
"key": "Quality",
"value": "Excellent"
}
],
"pageTitle": "",
"type": "simple",
"updatedAt": "2018-01-12T10:22:18.854Z",
"vendor": "Vendor_Name",
"originCountry": "country",
"requiresShipping": true,
"isDeleted": false,
"template": "productDetailSimple",
"workflow": {
"status": "new"
}
},
"variants": {},
"title": "Product",
"type": "simple",
"parcel": {
"weight": 25,
"height": 3,
"width": 10,
"length": 10
},
"shippingMethod": {
"shopId": "J8Bhq3uTtdgwZx3rz",
"shipmentQuotes": [Object],
"shipmentQuotesQueryStatus": {
"requestStatus": "success",
"numOfShippingMethodsFound": 11
},
"_id": "s3EJXrLsZe73RbLiD",
"address": {},
"shipmentMethod": {},
"paymentId": "nyybR5BNvDDrJrtwe",
"items": [
{
"_id": "JwR233jD2c4HKeYKq",
"productId": "BCTMZ6HTxFSppJESk",
"shopId": "J8Bhq3uTtdgwZx3rz",
"variantId": "CJoRBm9vRrorc9mxZ"
}
],
"workflow": {
"status": "new",
"workflow": ["String"]
}
},
"workflow": {
"status": "new",
"workflow": ["String"]
}
}
],
"shipping": [Object],
"email": "johndoe#mail.com",
"cartId": "L6sSGv4NR9rpbDbsd",
"createdAt": "2018-01-12T10:22:18.850Z"
}
The field items is an array of objects, I would like to update just a part of the object specifically the workflow field without touching other part of the objects in items array.
I was able to do this using a loop, but it caused some tests to fail. Is there a better of doing this with using a loop?
Thank you.
You can try findAndModify method.
Traverse to the workflow key ad try to set the value.
Hope this would help.

Update single sub document in multiple array in mgo

I have following mongodb (3.4.x) document, i code in golang with mgo driver
{
"id": "5981d4c2795a1b4a801ee027",
"scenarioId": "59804b10d8ee910085e33865",
"messages": [
{
"id": "5981d4c2795a1b4a801ee028",
"toQueue": [
{
"id": "5981d4c2795a1b4a801ee029",
"to": {
"email": "some#email.com"
},
"channel": "EMAIL",
"toType": "EMAIL",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
},
{
"id": "5981d4c2795a1b4a801ee02a",
"to": {
"phone": "+381631891245"
},
"channel": "SMS",
"toType": "PHONE",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
},
{
"id": "5981d4c2795a1b4a801ee02b",
"toQueue": [
{
"id": "5981d4c2795a1b4a801ee02c",
"to": {
"phone": "+123456789"
},
"channel": "SMS",
"toType": "PHONE",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"messageStages": [
{
"id": "5981d4c2795a1b4a801ee033",
"validityPeriod": 5,
"validityPeriodTimeUnit": "MINUTES",
"providerId": 5,
"email": {
"text": "this is the email text",
"subject": "and here the email subject"
},
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
]
}
and I know the value of messages.$.toQueue.id, where i want to update status.id in the related toQueue Array Item.
I tried to do it that way:
query = bson.M{
"messages.toQueue._id": toQueueId,
}
update = bson.M{
"$set": bson.M{
"messages.$.toQueue.$.status.id": status.Id,
"messages.$.toQueue.$.status.name": status.Name,
"messages.$.toQueue.$.status.groupId": status.GroupId,
"messages.$.toQueue.$.status.groupName": status.GroupName,
"messages.$.toQueue.$.status.description": status.Description,
},
}
err = cr.Update(query,update)
but multiple $ are not allowed. Without it's also not updateable.
Is there any way to update only the subdocument, which i found in query ?
Neil Lunn gave the right answer.
It's not possible to work with nested arrays the way I tried to do. And he is also right, that problem is coming from design mistake.
So I changed it as him and Markus W Mahlberg suggested to move the toQueue part in a separate collection, with messageId as a reference.

Grouping select with partial

Hello i have here this code:
public function getConversations($user, $limit, $page)
{
$offset = ($page - 1) * $limit;
$qb = $this->createQueryBuilder('message');
$qb
->select('message, partial o.{id}, partial userFrom.{id, username, avatar}, partial userTo.{id, username, avatar}, partial availability.{id, timeFrom}')
->leftJoin('message.from', 'userFrom')
->leftJoin('message.to', 'userTo')
->leftJoin('message.order', 'o')
->leftJoin('o.availabilities', 'availability')
->where($qb->expr()->orX(
$qb->expr()->eq('message.from', ':user'),
$qb->expr()->eq('message.to', ':user')
))
->setParameter('user', $user)
->setFirstResult($offset)
->setMaxResults($limit)
->addOrderBy('message.created', Criteria::DESC);
return $qb->getQuery()->getArrayResult();
}
I want to get only last message connected to each order. If i have 2 messages to order it gives me 2 rows but i need only one (the last one). I tried to use GROUP BY but it didn't work well. It wanted me to put all foreign ids to group by and then the result was really bad.
Result for this is:
{
"id": "813fa986-f89b-411d-8324-727e427cbc01",
"isRead": false,
"created": {
"date": "2016-12-12 18:01:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"content": "Hello to you too",
"contentType": "text",
"from": {
"id": "3e1806d6-f47e-48b4-afdb-1081d9555a3f",
"avatar": "",
"username": "User two"
},
"to": {
"id": "52ead9fa-b498-400b-967d-b49886ab3118",
"avatar": "",
"username": "User one"
},
"order": {
"id": "8349e718-405a-4e88-8155-3896e9a89fdf",
"availabilities": [
{
"id": "9ddc07e0-be3d-453c-b12f-0ee31bfce444",
"timeFrom": {
"date": "2016-12-03 12:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
}
]
}
},
{
"id": "813fa986-f89b-411d-8324-727e427cbc00",
"isRead": false,
"created": {
"date": "2016-12-12 18:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"content": "Helllooooooo",
"contentType": "text",
"from": {
"id": "52ead9fa-b498-400b-967d-b49886ab3118",
"avatar": "",
"username": "User one"
},
"to": {
"id": "3e1806d6-f47e-48b4-afdb-1081d9555a3f",
"avatar": "",
"username": "User two"
},
"order": {
"id": "8349e718-405a-4e88-8155-3896e9a89fdf",
"availabilities": [
{
"id": "9ddc07e0-be3d-453c-b12f-0ee31bfce444",
"timeFrom": {
"date": "2016-12-03 12:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
}
]
}
and should be just like this:
{
"id": "813fa986-f89b-411d-8324-727e427cbc01",
"isRead": false,
"created": {
"date": "2016-12-12 18:01:00.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"content": "Hello to you too",
"contentType": "text",
"from": {
"id": "3e1806d6-f47e-48b4-afdb-1081d9555a3f",
"avatar": "",
"username": "User two"
},
"to": {
"id": "52ead9fa-b498-400b-967d-b49886ab3118",
"avatar": "",
"username": "User one"
},
"order": {
"id": "8349e718-405a-4e88-8155-3896e9a89fdf",
"availabilities": [
{
"id": "9ddc07e0-be3d-453c-b12f-0ee31bfce444",
"timeFrom": {
"date": "2016-12-03 12:00:00.000000",
"timezone_type": 3,
"timezone": "UTC"
}
}
]
}
}