MongoDB query with a LEFT JOIN - json

I am doing a mongodb query or I was using a LEFT JOIN for the SQL database.
Here is the document of a profil :
{
"_id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"search" : "flarize",
"name" : "flarize",
"email" : "flarize.ba73#gmail.com",
"password" : "$2a$10$eYeOtEkEUyD7TFkjKvhZOuSSpvBolkL17TrPHuoHhOT8JrsQR0UKW",
"color" : 0,
"profil" : "",
"banner" : "",
"desc" : "",
"date" : 1540501286109,
"friend" : [
{
"id" : ObjectId("5bd19a92da24674fdabd26b6")
}
],
"groupes" : [ ]
}
I am currently using this request:
db.users.find({search: /f/}).limit(20);
this query just given profile according to the regex.
may I want more, if the id of the person who call this query is present in the section friend then we add :
is_friend: true
else add:
is_friend: false
EDIT :
For this query we have:
The id of the who call the request, and whe try to know if this id is present in the friend field.
EDIT
I try this but not working, return false.
herdb.users.aggregate([{$match:{"search":"flarize"}},
{$project:
{search: 1, name: 1, color: 1, profil: 1, banner: 1, desc: 1, date: 1, friend:10, groupes:10,
is_friend:
{$cond:[
{$eq:["$friend.id", ObjectId("5bd19a92da24674fdabd26b6")]},
true,
false]
}
}
}
]).pretty();
Thank you for helping me.

Use $unwind for a friend before matching it's id
$eq is not working for an array.
db.getCollection('tests').aggregate([
{ $match: {"search":"flarize"} },
{ $unwind: "$friend"},
{ $project:{
search: 1, name: 1, color: 1, profil: 1, banner: 1, desc: 1, date: 1, friend:10, groupes:10,
is_friend: { $cond: [
{ $eq :["$friend.id", ObjectId("5bd19a92da24674fdabd26b6")]}, true, false ]}
}
}
]);
Output:
/* 1 */
{
"_id" : ObjectId("5bd22f28f77cfb1f6ce503ca"),
"search" : "flarize",
"name" : "flarize",
"color" : 0,
"profil" : "",
"banner" : "",
"desc" : "",
"date" : NumberLong(1540501286109),
"friend" : {
"id" : ObjectId("5bd19a92da24674fdabd26b6"),
"id" : ObjectId("5bd19a92da24674fdabd26b4"),
"id" : ObjectId("5bd19a92da24674fdabd26b2"),
"id" : ObjectId("5bd19a92da24674fdabd26b1")
},
"groupes" : [],
"is_friend" : true
}
And if you want friend back it to an array list:
db.getCollection('tests').aggregate([
{ $match: {"search":"flarize"} },
{ $unwind: "$friend"},
{ $project:
{
search: 1, name: 1, color: 1, profil: 1, banner: 1, desc: 1, date: 1, friend:10, groupes:10,
is_friend: { $cond: [
{ $eq :["$friend.id", ObjectId("5bd19a92da24674fdabd26b6")]}, true, false ]}
}
},
{$group : {
_id: "$_id",
search : {$first: "$search"},
name : {$first: "$name"},
color : {$first: "$color"},
profil : {$first: "$profil"},
banner : {$first: "$banner"},
desc : {$first: "$desc"},
date : {$first: "$date"},
groupes : {$first: "$groupes"},
friend : {$push: "$friend"},
is_friend: {$first: "$is_friend"}
}}
])

Related

Highchart reduce gap size in heatmap and data missing

Somehow the gap is not reduced, as shown in the picture below:
I am using a Highcharts Heatmap. Please help me to reduce the gap between the intervals and the line should be closer. When we increase the data, some data is not showing on the graph and they are skipped. The data seems to be missing somewhere.
Highcharts
.stockChart(
'container',
{
chart : {
type : 'heatmap',
marginTop : 40,
height : 500,
width : 900,
panning : true,
followTouchMove : true,
pinchType : 0,
followPointer : true,
inverted : true,
},
data : {
csv : data,
},
navigator : {
top : 40,
},
rangeSelector : {
buttons : [ {
count : 1,
type : 'minute',
text : '1M'
}, {
count : 5,
type : 'minute',
text : '5M'
}, {
type : 'all',
text : 'All'
} ],
inputEnabled : false,
enabled : false,
selected : 0
},
title : {
text : 'Live random data'
},
exporting : {
enabled : true,
buttons : {
contextButton : {
menuItems : [
{
textKey : 'viewData',
onclick : function() {
this.viewData();
$('#pausereset')
.toggleClass(
'optionsettable');
}
},
{
separator : true
},
{
textKey : 'downloadPNG',
onclick : function() {
var title = this.title.textStr;
this.exportChart({
type : 'image/png',
filename : title
});
}
},
{
textKey : 'downloadJPEG',
onclick : function() {
var title = this.title.textStr;
this
.exportChart({
type : 'image/jpeg',
filename : title
});
}
},
{
textKey : 'downloadPDF',
onclick : function() {
var title = this.title.textStr;
this
.exportChart({
type : 'application/pdf',
filename : title
});
}
},
{
textKey : 'downloadSVG',
onclick : function() {
var title = this.title.textStr;
this
.exportChart({
type : 'image/svg+xml',
filename : title
});
}
} ]
}
}
},
yAxis : {
scrollbar : {
enabled : true,
showFull : true
},
title : {
text : null
},
labels : {
format : '{value}:00'
},
/* minPadding : 50,
maxPadding : 20, */
/* tickPositions : [ 0, 6, 12, 18, 24 ], */
tickWidth : 0.5,
/* min : 0,
max : 33 */
},
xAxis : {
reversed : true,
scrollbar : {
enabled : true,
showFull : true
},
tickPixelInterval : 0.5,
},
plotOptions : {
dataLabels : {
enabled : true
},
heatmap : {
allowPointSelect : true
},
series : {
pointPadding : 0,
groupPadding : 0.1,
}
},
colorAxis : {
stops : [ [ 0, '#84D984' ], [ 0.5, '#127B12' ],
[ 0.9, '#005500' ] ],
min : -5
},
series : [ {
type : 'heatmap',
name : 'Random data',
borderWidth : 0,
showInNavigator : true,
turboThreshold : 0,
cropThreshold : 300,
/* colsize : 0.1 * 36e5, */
pointPadding : 0,
colsize : 0.1 * 36e5,
rowsize : 1,
tooltip : {
headerFormat : 'Temperature<br/>',
pointFormat : '{point.x: %H}:{point.x: %m} - {point.y}:00: <b>{point.value} ℃</b>'
},
} ]
});
Here is the jsfiddle link
You just need to increase the series.colsize value. In this case, you can set it equal to one hour interval, just like that:
series: [{
type:'heatmap',
borderWidth: 0,
pointWidth: '100%',
colsize: 36e5, // one hour
tooltip: {
headerFormat: 'Temperature<br/>',
pointFormat: '{point.x:%e %b, %Y} {point.y}:00: <b>{point.value} ℃</b>'
}
}]
Live example: http://jsfiddle.net/zpvdweab/1/

What's the correct JSON structure when we have fields with flags?

We have to return a object with data about user configuration. Some fields have a property indicating if this field is locked, if it's mandatory, etc.
What's the right structure for return this object in as JSON? We have consider
Option 1:
{
"id": "123456",
"config":{
"field1" : "some-value",
"field2" : true,
"field3" : 23.1,
"locked-fields" : ["field1", "field3"],
"mandatory-fields" : ["field2", "field3"]
},
"data" : {
"data-section-1":{
"data-field1" : "some-value",
"data-field2" : "some-value",
"locked-fields" : ["data-field1"],
"mandatory-fields" : ["data-field2"]
},
"data-section-2":{
"data-field3" : "some-value",
"data-field4" : "some-value",
"locked-fields" : ["data-field3", "data-field4"]
}
}
}
Option 2:
{
"id": "123456",
"config":{
"field1" : { "value" : "some-value", "locked" : true, "mandatory" : false},
"field2" : { "value" : true, "locked" : false, "mandatory" : true},
"field3" : { "value" : 23.1, "locked" : true, "mandatory" : true}
},
"data" : {
"data-section-1":{
"data-field1" : { "value" : "some-value", "locked" : true, "mandatory" : false},
"data-field2" : { "value" : "some-value", "locked" : false, "mandatory" : true}
},
"data-section-2":{
"data-field3" : { "value" : "some-value", "locked" : true, "mandatory" : false},
"data-field4" : { "value" : "some-value", "locked" : true, "mandatory" : false}
}
}
}
Which is the most correct?
I would choose option 2.
"Locked" or "Mandatory" are for me some kind of properties which object (Field in that case) has. Second Json represents "locked" and "mandatory" as such properties of Field object, so it looks better.

Query to return a field from a nested json using MongoDB

My database has data in the following format :
{ "_id" : ObjectId( "abcd" ),
"coordinate" : [somevalue, somevalue],
"value" : [
{ "time" : 1,
"characteristics" : "pqrs" },
{ "time" : 10,
"characteristics" : "pqrs" } ] }
I want to find the field closest coordinate and a time that is less than or equal to a given value.
Currently I'm using this query :
db.collection.aggregate({
coordinate: {
$geoNear: [latitude, longitude],
$maxDistance: 10
},
"value.time": {
$lte: 5
}
})
This one returned the entire entry, but what I wanted is the field:
{ "time" : 1, "characteristics" : "pqrs" }
Is it even possible to just return this field ? What if there are multiple result and I just want the one that's closest to my value.time input ?
You can perform an aggregation to :
$match items with specified coordinate and value.time
$filter value array to remove everything < 5
$unwind value array
$group by max value
Query is :
db.collection.aggregate({
$match: {
coordinate: {
$geoNear: [0, 0],
$maxDistance: 10
},
"value.time": {
$lte: 5
}
}
}, {
$project: {
value: {
$filter: {
input: "$value",
as: "value",
cond: { $lte: ["$$value.time", 5] }
}
}
}
}, {
$unwind: "$value"
}, {
$group: {
_id: "$_id",
time: { $max: "$value.time" },
characteristics: { $first: "$value.characteristics" }
}
})
Sample output :
{ "_id" : ObjectId("588a8c3080a14de2d654eb7b"), "time" : 4, "characteristics" : "pqrs" }
{ "_id" : ObjectId("588a89327fe89686fd2210b2"), "time" : 1, "characteristics" : "pqrs" }

how to use aggregate for group and count in mongoose?

I have json object in my db like as follows:
{
'name':'test1',
'game':'cric'
},
{
'name':'test1',
'game':'cric'
},
{
'name':'test1',
'game':'football'
},
{
'name':'test2'
'game':'football'
}
I am trying to get output as follows
{
'name':'test1'
'game':[{cric: 2}, {football:1}],
'totalCount': 3
}
I used aggregate query for that.
group {'_id':{name:'$name'}, {game:{$addToSet:$game}}
project {name : $name, game: $game}
I got output as
{name: 'test1', 'game':[cric, football]}
Now i have question that, how can i get count of game. it current example for cricket it is 2 and for football 1 for test1 user
A similar question is answered here.
For your particular case it would be:
db.collection.aggregate([
{
$group: {
_id: { name: "$name", game: "$game" },
games: { "$push": "$game" },
total: { "$sum": 1 }
}
},
{
$group: {
_id: { name: "$_id.name" },
games: { $addToSet: { game: "$_id.game", sum:"$total" } }
}
}
])
And the result should look like:
{
"result" : [
{
"_id" : {
"name" : "test1"
},
"games" : [
{
"game" : "cric",
"sum" : 2
},
{
"game" : "football",
"sum" : 1
}
]
},
{
"_id" : {
"name" : "test2"
},
"games" : [
{
"game" : "football",
"sum" : 1
}
]
}
],
"ok" : 1
}
Here is my solution to test1 name record
db.getCollection('COLLECTION_NAME').aggregate([
{$match : {name : "test1"}},
{
$group: {
_id: "$game" ,
total: { "$sum": 1 },
name : {$first : "$name"}
}
},
{
$group: {
_id : "$name",
games: { $addToSet: { game: "$_id", sum:"$total" } },
totalCount : {$sum : "$total"}
}
}
])

How to filter a nested SwiftyJSON array

I have a SwiftyJSON array that is nested several levels and I need to filter the array based on a value in the lowest level. Below is an example of an array. I need to filter it on Active == true. What is the most efficient way to accomplish this?
var colors = JSON([
"Apple" : [
"Yellow" : [
"Active" : true,
"Working" : true,
"Value" : 0
],
"Red" : [
"Active" : false,
"Working" : true,
"Value" : 0
]
],
"Banana" : [
"Blue" : [
"Active" : false,
"Working" : true,
"Value" : 0
],
"Green" : [
"Active" : true,
"Working" : true,
"Value" : 0
]
]
])
Desired output:
"Apple" : [
"Yellow" : [
"Active" : true,
"Working" : true,
"Value" : 0
]
],
"Banana" : [
"Green" : [
"Active" : true,
"Working" : true,
"Value" : 0
]
]
Check this out
var filteredArray = [JSON]()
for item in colors {
for subItem in item.1 {
if subItem.1["Active"].boolValue {
filteredArray.append(JSON([item.0:JSON([subItem.0:subItem.1])]))
}
}
}
print(filteredArray)
Output is the array of Dictionaries of filtered sub dictionaries with Active true:
[{
"Apple" : {
"Yellow" : {
"Working" : true,
"Value" : 0,
"Active" : true
}
}
}, {
"Banana" : {
"Green" : {
"Working" : true,
"Value" : 0,
"Active" : true
}
}
}]
you can create a loop that will read all colors and within this loop to create one that will read the other items in the second array. Within the second is you check if the item is valid or not and save it in another array
let activeItems = []
for item in colors {
for i in item as NSDictionary {
if i.objectForKey("Active") == true {
activeItems.addObject(i)
}
}
}
var result = [String:[String:JSON]]()
for (key, json) in colors.dictionaryValue {
let filtered = json.dictionaryValue.filter{$0.1["Active"].boolValue}
guard filtered.count > 0 else { continue }
var subDic = [String:JSON]()
filtered.forEach{subDic[$0.0] = $0.1}
result[key] = subDic
}
print(result)