mongodb - filter collection by string array contains "" - mongodb

For the below document, I want to write mongodb query to get the result.
[{
"id": "1",
"class": "class1",
"value": "xyz"
}, {
"id": "2",
"class": "class2",
"value": "abc"
}, {
"id": "3",
"class": "class3",
"value": "123"
}, {
"id": "4",
"class": "class4"
}, {
"id": "5",
"class": "class5",
"value": ""
}
]
The search parameter is an array of values - ["abc", "xyz", ""] and this is
going to look attribute "value"
The output should be below and in this case, the third item in the search array "" is pointing to collection that has "id" - 4 and 5 :
[{
"id": "1",
"class": "class1",
"value": "xyz"
}, {
"id": "2",
"class": "class2",
"value": "abc"
}, {
"id": "4",
"class": "class4"
}, {
"id": "5",
"class": "class5",
"value": ""
}
]
Please assist to provide the mongodb query to get the result like this

Whenever you have blank string you can add null in array, like this,
db.collection.find({
value: {
$in: ["abc", "xyz", "", null]
}
})

Related

the result of mongo export is not a valid json

I use this command to export data from db, but it not a valid json, it doesn't have comma at the end of item, how to fix this issue?
https://docs.mongodb.com/database-tools/mongoexport/#syntax
{
"id" : "1",
"name" : "a"
}
{
"id" : "2",
"name" : "b"
}
{
"id": "3",
"name": "c"
}
{
"id": "4",
"name": "d"
}
Use the --jsonArray option (see https://docs.mongodb.com/database-tools/mongoexport/#std-option-mongoexport.--jsonArray )
mongoexport --quiet -d test -c test --pretty --jsonArray
[{
"_id": {
"$oid": "611aca090848cb8cab2943f7"
},
"id": "1",
"name": "a"
},
{
"_id": {
"$oid": "611aca110848cb8cab2943f8"
},
"id": "2",
"name": "b"
},
{
"_id": {
"$oid": "611aca180848cb8cab2943f9"
},
"id": "3",
"name": "c"
},
{
"_id": {
"$oid": "611aca1d0848cb8cab2943fa"
},
"id": "4",
"name": "d"
}]

Filter Nested Array Items CosmosDb

Is it possible to filter array items in CosmosDb? for example I just need customer info and the first pet(in an array)
Current result:
[
{
"CustomerId": "100",
"name": "John",
"lastName": "Doe",
"pets": [
{
"id": "pet01",
"CustomerId": "100",
"name": "1st pet"
},
{
"id": "pet02",
"CustomerId": "100",
"name": "2nd pet"
}
]
}
]
Expected:
[
{
"CustomerId": "100",
"name": "John",
"lastName": "Doe",
"pets": [
{
"id": "pet01",
"CustomerId": "100",
"name": "1st pet"
}
]
}
]
You can use ARRAY_SLICE function.
SQL:
SELECT c.CustomerId,c.name,c.lastName,ARRAY_SLICE(c.pets,0,1) as pets
FROM c
Result:
[
{
"CustomerId": "100",
"name": "John",
"lastName": "Doe",
"pets": [
{
"id": "pet01",
"CustomerId": "100",
"name": "1st pet"
}
]
}
]

Dataweave sort by using custom list

I have a requirement to sort data based on a defined list, not alphabetically and not numerically.
Sorting order is in a variable "sortOrder"
%dw 2.0
output application/json
var sortOrder = [ "Brad", "Alex", "Dan", "Chad"]
var myPayload = [
{
"Name": "Dan",
"Id": "3"
},
{
"Name": "Brad",
"Id": "4"
},
{
"Name": "Alex",
"Id": "2"
}
{
"Name": "Chad",
"Id": "1"
}
{
"Name": "Dan",
"Id": "5"
}
]
---
myPayload
The output needs to be like this.
[
{
"Name": "Brad",
"Id": "4"
},
{
"Name": "Alex",
"Id": "2"
},
{
"Name": "Dan",
"Id": "3"
},
{
"Name": "Dan",
"Id": "5"
},
{
"Name": "Chad",
"Id": "1"
}
]
There are 2 entries for Dan, in this case the sorting should be based on "Id"
You can order by the index of the sortOrder elements using Name to find it.
%dw 2.0
import * from dw::core::Arrays
output application/json
var sortOrder = [ "Brad", "Alex", "Dan", "Chad"]
var myPayload = [
{
"Name": "Dan",
"Id": "3"
},
{
"Name": "Brad",
"Id": "4"
},
{
"Name": "Alex",
"Id": "2"
},
{
"Name": "Chad",
"Id": "1"
},
{
"Name": "Dan",
"Id": "5"
}
]
---
myPayload orderBy( indexOf(sortOrder, $.Name) )

mongoDB read performance difference between one to many models and normalized models

here are 2 possibilities for a note taking database that will have multiple notes for multiple users to keep track of
1.
[
{
"_id": "abcd",
"userInfo": {
"userID": "1",
"notes": [
{
"noteID": "1",
"text": "123"
},
{
"noteID": "2",
"text": "456"
},
{
"noteID": "3",
"text": "789"
}
]
}
},
{
"_id": "efgh",
"userInfo": {
"userID": "2",
"notes": [
{
"noteID": "1",
"text": "123"
},
{
"noteID": "2",
"text": "456"
}
]
}
}
]
And the 2nd option:
[
{
"_id": "abcd",
"userID": "1",
"noteID": "1",
"text": "123"
},
{
"_id": "efgh",
"userID": "1",
"noteID": "2",
"text": "456"
},
{
"_id": "ijkl",
"userID": "1",
"noteID": "3",
"text": "789"
},
{
"_id": "mnop",
"userID": "2",
"noteID": "1",
"text": "123"
},
{
"_id": "wxyz",
"userID": "2",
"noteID": "2",
"text": "123"
}
]
I'd expect 1 to have a much better performance when it comes to loading notes for a single user(if the user has a ton of notes). However, 2nd option is much better when modifying and adding individual notes.

Laravel Eloquent API resource is returning empty array when no data

I am using etrepat baum laravel module to store and generate hierarchy. Also using eloquent api resource to customize the json data returned.
Currently empty children are returned if no children available. Is it possible to have children only if available?
Current Result
[{
"id": "1",
"text": "Vegetables",
"children": [{
"id": "2",
"text": "Onion",
"children": []
}, {
"id": "3",
"text": "Tomato",
"children": []
}, {
"id": "4",
"text": "Chilli",
"children": []
}, {
"id": "5",
"text": "Potato",
"children": []
}]
}, {
"id": "6",
"text": "Fruits",
"children": [{
"id": "7",
"text": "Apple",
"children": [{
"id": "12",
"text": "Red Apple",
"children": []
}, {
"id": "13",
"text": "Green Apple",
"children": []
}]
}, {
"id": "8",
"text": "Banana",
"children": [{
"id": "14",
"text": "Red Banana",
"children": []
}, {
"id": "15",
"text": "Yellow Banana",
"children": []
}]
}, {
"id": "9",
"text": "Orange",
"children": []
}, {
"id": "10",
"text": "Papaya",
"children": []
}, {
"id": "11",
"text": "Guava",
"children": []
}]
}]
Expected Result
[{
"id": "1",
"text": "Vegetables",
"children": [{
"id": "2",
"text": "Onion"
}, {
"id": "3",
"text": "Tomato"
}, {
"id": "4",
"text": "Chilli"
}, {
"id": "5",
"text": "Potato"
}]
}, {
"id": "6",
"text": "Fruits",
"children": [{
"id": "7",
"text": "Apple",
"children": [{
"id": "12",
"text": "Red Apple"
}, {
"id": "13",
"text": "Green Apple"
}]
}, {
"id": "8",
"text": "Banana",
"children": [{
"id": "14",
"text": "Red Banana"
}, {
"id": "15",
"text": "Yellow Banana"
}]
}, {
"id": "9",
"text": "Orange"
}, {
"id": "10",
"text": "Papaya"
}, {
"id": "11",
"text": "Guava"
}]
}]
CategoryResource.php
public function toArray($request) {
return [
'id' => (string) $this->id,
'text' => (string) $this->name,
'children' => CategoryResource::collection($this->children)
];
}
CategoryController.php
public function index()
{
CategoryResource::withoutWrapping();
$categories = Category::all()->toHierarchy()->values();
return new CategoryResourceCollection($categories);
}
You can check before adding it to the array and if it's empty don't add it to the returned array :
public function toArray($request) {
$result = [
'id' => (string) $this->id,
'text' => (string) $this->name
];
$child = CategoryResource::collection($this->children);
if (!$child->isEmpty()) {
$result['children'] = $child;
}
return $result;
}
In Laravel 5.7, you could use:
public function toArray($request) {
return [
'id' => (string) $this->id,
'text' => (string) $this->name,
'children' => CategoryResource::collection($this->whenLoaded('children'))
];
}
Correct answer for Laravel 5.7
public function toArray($request) {
return [
'id' => (string) $this->id,
'text' => (string) $this->name,
'children' => CategoryResource::collection($this->when(!$this->children->isEmpty()))
];
}
In this example, if the children is empty, the children key will be removed from the resource response entirely before it is sent to the client.
If you also need this to work correctly with Conditional Relationships (i.e. not trigger loading of each relationship just to check whether it's empty), this is the best way I could figure out (based partly on the other answers here, plus some trial and error)
public function toArray($request)
{
$children = $this->whenLoaded('children');
return [
'id' => $this->id,
'text' => $this->text,
'children' => $this->when(method_exists($children, 'isEmpty') && !$children->isEmpty(), CategoryResource::collection($children))
];
}