MongoDB Aggregation SQL Union and SQL Exists like clause - sql

I would like to make a MongoDB aggregation Query on data like this :
Collection A
{
_id : 1,
Active : true,
hasQuery : false,
Running : false,
}
{
_id : 2,
Active : true,
hasQuery : true,
Running : false,
}
{
_id : 3,
Active : true,
hasQuery : false,
Running : true,
}
{
_id : 4,
Active : true,
hasQuery : true,
Running : true,
}
{
_id : 5,
Active : false,
hasQuery : false,
Running : false,
}
{
_id : 6,
Active : false,
hasQuery : false,
Running : true,
}
This JSON data could be represented by a table architechture like this
Table A
PrimaryKey | Active | hasQuery | Running
1 | true | false | false
2 | true | true | false
3 | true | false | true
4 | true | true | true
5 | false | false | false
6 | false | false | true
If I apply the following query on the table :
select * from A where Exists(Select * from A where A.Running=true and A.hasQuery=true) and A.Running=false and A.hasQuery=false and A.Active=true
union
select * from A where not Exists(Select * from A where A.Running=true and A.hasQuery=true) and A.Running=false and A.Active=true
I get theses results :
In MongoDB :
{
_id : 1,
Active : true,
hasQuery : false,
Running : false,
}
{
_id : 2,
Active : true,
hasQuery : true,
Running : false,
}
{
_id : 5,
Active : false,
hasQuery : false,
Running : false,
}
in SQL :
PrimaryKey | Active | hasQuery | Running
1 | true | false | false
2 | true | true | false
5 | false | false | false
How to do the same thing with mongoDB aggregation ?

I managed to do it with that code :
db.test.aggregate(
{
$project:
{
RunningActiveRecordHasQuery:
{
$cond: { if: { $and: [ "$Running", "$hasQuery", "$Active"] }, then: true, else: false }
}
}
}
,
{
$match: {
RunningActiveRecordHasQuery : true
}
},
function (err, results) {
if (!err ) {
console.log (results.result);
match={}
if (results.length>0) {
match.AnyNotRunningActiveRecordHavingNoQuery=true;
} else {
match.AnyActiveRecordNotRunning=true;
}
db.test.aggregate(
{
$project:
{
_id: 1,
Running : 1,
Active : 1,
hasQuery : 1,
AnyNotRunningActiveRecordHavingNoQuery:
{
$cond: { if: { $and: [ {$eq: [ "$Running", false ] }, {$eq : [ "$hasQuery", false]}, "$Active"] }, then: true, else: false }
},
AnyActiveRecordNotRunning:
{
$cond: { if: { $and: [ {$eq: [ "$Running", false ] }, "$Active"] }, then: true, else: false }
}
}
}
,
{
$match: match
},
function (err, docs) {
}
)
}
}
)
It uses to aggregation to make things working.

Related

MongoDB join by array element value equals to field value

suppose you have 2 collections as following:
== Device ==
[{
machineId: 'Machine1',
plug:{ plugId: 'CE', active: true }
}
,{
machineId: 'Machine2',
plug: { plugId: 'T2', active: false }
}
]
=== Machine ===
[
{ _id: 'Machine1',
plugs: [
{'CE':{origin:'Italy', active: true}}
]
},
{ _id: 'Machine2',
plugs: [
{'CE': {origin:'France', active: false}}
]
}
]
==========
I need join this two collections by next condition:
Device.machineId = Machine._id,
Device.plug.plugId == Machine.plugs[0] and
Device.plug.active <> Machine.plugs[0].active
How can I do that, please?

Compare two result sets if employee Id is matches change status flag to true

Can anyone kindly provide the DataWeave logic for the below output structure based on the two Inputs resultSet1 and resultSet2. if the id is matched change the status to true and by default, the status is false?
resultSet1 = [{
id: "12334",
},
{
id: "13357",
}
]
resultSet2 = [
{
id: "12334",
status: false
},
{
id: "11521",
status: false
},
{
id: "13357",
status: false
}
final output:
[
{
id: "12334",
status: true
},
{
id: "11521",
status: false
},
{
id: "13357",
status: true
}
]
Thanks in advance!
this solution iterates resultSet2 and for each item checks if the ID is in the list of IDs of resultSet1
resultSet2 map {
id: $.id,
status: resultSet1.id contains $.id
}

mongodb aggregate distinct count

Realise this topic has been asked many times - but the advice hasn't helped me solve this problem.
The following query is trying to determine the presence of sales on a given weekday using ISODay. Because the query will be run at the start of the month, I need to know how many occurrences of the specific ISOday occur in the month.
var query = { eventType: 'Sale', site : 4, tank: 1, txnDate : { "$gt" : new Date('2018-08-01T00:00:00') } };
db.tankevent.aggregate([
{ $match: query },
{ $project : {
isoDay: { $isoDayOfWeek: "$txnDate" },
dayDate: { $dateToString: { format: "%d", date:"$txnDate" } }
}
},
{ $group:
{ _id : { isoday: "$isoDay", dday: "$dayDate" }, count: { "$sum" : 1 } }
},
{ $sort: { "_id.isoday": 1, "_id.dday": 1 } }
])
provides the following output
/* 1 */
{
"_id" : {
"isoday" : 1,
"dday" : "06"
},
"count" : 62.0
}
/* 2 */
{
"_id" : {
"isoday" : 1,
"dday" : "13"
},
"count" : 69.0
}
/* 3 */
{
"_id" : {
"isoday" : 1,
"dday" : "20"
},
"count" : 72.0
}
/* 4 */
{
"_id" : {
"isoday" : 2,
"dday" : "07"
},
"count" : 75.0
}
I am trying to have "count" represent the number of unique "dday" records - so using the output above, I want count to be "3" for isoDay = 1. At the moment count is reporting number of sales events that occurred for the group combination
All you need to do is have the grouping twice.
db.tankevent.aggregate([
{ $match: query },
{ $project : {
isoDay: { $isoDayOfWeek: "$txnDate" },
dayDate: { $dateToString: { format: "%d", date:"$txnDate" } }
}
},
{ $group:
{ _id : { isoday: "$isoDay", dday: "$dayDate" }, count: { "$sum" : 1 } }
},
{ $project : {
isoDay_Final: "$_id.isoday"
}
},
{ $group:
{ _id : "$isoDay_Final", count: { "$sum" : 1 } }
},
{ $sort: { "_id": 1 } }
])

Datatables sort images on title tag

I have a question about using a custom sorting option for datatables.
I have a table with only images in the last column. The images use the title tag, where I want to sort them on.
So, I use this code to set the sorting:
<script type="text/javascript">
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"title-string-pre": function ( a ) {
return a.match(/title="(.*?)"/)[1].toLowerCase();
},
"title-string-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"title-string-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
$(document).ready(function() {
$('#customertable').dataTable( {
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0,1 ] },
{ "sType": "title-string-asc", "aTargets": [ 4 ] }
],
"bPaginate": false,
"bLengthChange": false,
"bFilter": false,
"bInfo": false,
"bAutoWidth": false,
"bSortCellsTop": true
} );
} );
</script>
However, when I click on the header of column 4, it does not work and Chrome reports errors "Property 'title-string-asc-desc' of object # is not a function"
and
"Property 'title-string-asc-asc' of object # is not a function"
What am I doing wrong?
Found the answer, but don't understand it.
Changed
{ "sType": "title-string-asc", "aTargets": [ 4 ] }
to
{ "sType": "title-string", "aTargets": [ 4 ] }
Now it works. But why? "title-string" is defined nowhere. How can javascript link that string to the content of a title tag?

How does MongoDB index arrays?

In MongoDB, if I were to store an array (say ["red", "blue"]) in a field "color", does it index "red" and "blue" so I could query for "red", for example, or does in make {"red", "blue"} a composite index?
When it comes to indexing arrays, MongoDB indexes each value of the array so you can query for individual items, such as "red." For example:
> db.col1.save({'colors': ['red','blue']})
> db.col1.ensureIndex({'colors':1})
> db.col1.find({'colors': 'red'})
{ "_id" : ObjectId("4ccc78f97cf9bdc2a2e54ee9"), "colors" : [ "red", "blue" ] }
> db.col1.find({'colors': 'blue'})
{ "_id" : ObjectId("4ccc78f97cf9bdc2a2e54ee9"), "colors" : [ "red", "blue" ] }
For more information, check out MongoDB's documentation on Multikeys: http://www.mongodb.org/display/DOCS/Multikeys
You can simply test index usage by appending "explain" to your query:
> db.col1.save({'colors': ['red','blue']})
# without index
> db.col1.find({'colors': 'red'}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "protrain.col1",
"indexFilterSet" : false,
"parsedQuery" : {
"colors" : {
"$eq" : "red"
}
},
"winningPlan" : {
"stage" : "COLLSCAN", <--- simple column scan
"filter" : {
"colors" : {
"$eq" : "red"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "bee34f15fe28",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
},
"ok" : 1
}
# query with index
> db.col1.createIndex( { "colors":1 } )
> db.col1.find({'colors': 'red'}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "protrain.col1",
"indexFilterSet" : false,
"parsedQuery" : {
"colors" : {
"$eq" : "red"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN", <!---- INDEX HAS BEEN USED
"keyPattern" : {
"colors" : 1
},
"indexName" : "colors_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"colors" : [
"colors"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"colors" : [
"[\"red\", \"red\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "bee34f15fe28",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
},
"ok" : 1
}
For structures where you have structured indexes, you could use the array position to index fields inside arrays:
{
'_id': 'BB167E2D61909E848EBC96C7B33251AC',
'hist': {
'map': {
'10': 1
}
},
'wayPoints': [{
'bhf_name': 'Zinsgutstr.(Berlin)',
'ext_no': 900180542,
'lat': 52.435158,
'lon': 13.559086,
'puic': 86,
'time': {
'dateTime': '2018-01-10T09: 38: 00',
'offset': {
'totalSeconds': 3600
}
},
'train_name': 'Bus162'
},
{
'bhf_name': 'SAdlershof(Berlin)',
'ext_no': 900193002,
'lat': 52.435104,
'lon': 13.54055,
'puic': 86,
'time': {
'dateTime': '2018-01-10T09: 44: 00',
'offset': {
'totalSeconds': 3600
}
},
'train_name': 'Bus162'
}]
}
db.col.createIndex( { "wayPoints.0.ext_no":1 } )
db.col.createIndex( { "wayPoints.0.train_name":1 } )
db.col.createIndex( { "wayPoints.1.ext_no":1 } )
db.col.createIndex( { "wayPoints.1.train_name":1 } )
> db.col.find(
... {
... "wayPoints.ext_no": 900180542
... }
... ,
... {
... "wayPoints.ext_no":1,
... "wayPoints.train_name":1,
... "wayPoints.time":1
... }
... ).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.col",
"indexFilterSet" : false,
"parsedQuery" : {
"wayPoints.ext_no" : {
"$eq" : 900180542
}
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"wayPoints.ext_no" : 1,
"wayPoints.train_name" : 1,
"wayPoints.time" : 1
},
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"wayPoints.ext_no" : 1
},
"indexName" : "wayPoints.ext_no_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"wayPoints.ext_no" : [
"wayPoints"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"wayPoints.ext_no" : [
"[900180542.0, 900180542.0]"
]
}
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "bee34f15fe28",
"port" : 27017,
"version" : "3.4.4",
"gitVersion" : "888390515874a9debd1b6c5d36559ca86b44babd"
},
"ok" : 1
}