Related
Recently I'm working with a Mongodb database. Here is the data model of the document I need to run a query on:
{
"creation_date": {
"$date": {
"$numberLong": "1641981205813"
}
},
"user_id": {
"$oid": "61dedd8b7a520461dd78016b"
},
"products": [
{
"_id": {
"$oid": "61dede397a520461dd7818bd"
},
"product_id": {
"$oid": "615071ae8b66e1e9a3d6ea50"
},
"payment": true,
"support_all_payment": false,
"term_ids": null
}
],
"carts_info": [
{
"_id": {
"$oid": "61dede397a520461dd7818be"
},
"support_type": null,
"support_price": 0,
"product_price": 11000,
"product_type": "all",
"final_price": 11000,
"product_id": {
"$oid": "615071ae8b66e1e9a3d6ea50"
}
}
],
"_des": "initial_payment",
"_type": "online",
"_token": "9e0cb4d111f642f1a6f482bb04f1f57b",
"_price": 11000,
"_status": "unpaid",
"_terminal_id": "12605682",
"__v": 0,
"additional_information": {
"saman_bank": {
"MID": "0",
"ResNum": "61dede387a520461dd7818bb",
"State": "CanceledByUser",
"TraceNo": "",
"Wage": "",
"Rrn": "",
"SecurePan": "",
"HashedCardNumber": "",
"Status": "1"
}
}
}
This collection is user orders. I need to count the orders for today. So, I need such a equivalent query for Mongodb Compass the same as this SQL:
SELECT count(1) num,
date(creation_date) date
FROM orders
WHERE date(creation_date) = "2023-02-16"
GROUP BY date
Any idea how can I run this logic on Mongodb Compass?
Use $dateTrunc to perform date only operations.
db.collection.aggregate([
{
"$match": {
$expr: {
$eq: [
{
$dateTrunc: {
date: "$creation_date",
unit: "day"
}
},
ISODate("2022-01-12")
]
}
}
},
{
$group: {
_id: {
$dateTrunc: {
date: "$creation_date",
unit: "day"
}
},
num: {
$sum: 1
}
}
}
])
Mongo Playground
For OP's MongoDB v3.6, we can use $dateToString to perform string comparison on a date-only string.
db.collection.aggregate([
{
$addFields: {
dateOnly: {
"$dateToString": {
"date": "$creation_date",
"format": "%Y-%m-%d"
}
}
}
},
{
$match: {
dateOnly: "2022-01-12"
}
},
{
$group: {
_id: null,
num: {
$sum: 1
}
}
}
])
Mongo Playground
I'm pretty sure the below can be done, I'm struggling to understand how to do it in MongoDB.
My data is structured like this (demo data):
db={
"recipes": [
{
"id": 1,
"name": "flatbread pizza",
"ingredients": {
"1010": 1,
"1020": 2,
"1030": 200
}
},
{
"id": 2,
"name": "cheese sandwich",
"ingredients": {
"1040": 1,
"1050": 2
}
}
],
"ingredients": [
{
"id": 1010,
"name": "flatbread",
"unit": "pieces"
},
{
"id": 1020,
"name": "garlic",
"unit": "clove"
},
{
"id": 1030,
"name": "tomato sauce",
"unit": "ml"
},
{
"id": 1040,
"name": "bread",
"unit": "slices"
},
{
"id": 1050,
"name": "cheese",
"unit": "slices"
}
]
}
The output I'm trying to achieve would look like this:
[
{
"id": 1,
"name": "flatbread pizza",
“flatbread”: “1 pieces”,
“garlic”: “2 cloves”,
“tomato sauce”: “200 ml”
},
{
"id": 2,
"name": "cheese sandwich",
“bread”: “1 slices”,
“cheese”: “2 slices”
}
]
I've tried several approaches, and I get stuck at the bit where I need to do a lookup based on the ingredient name (which actually is the id). I tried using $objectToArray to turn it into a k-v document, but then I get stuck in how to construct the lookup pipeline.
This is not a simple solution, and probably can be improved:
db.recipes.aggregate([
{
"$addFields": {
ingredientsParts: {
"$objectToArray": "$ingredients"
}
}
},
{
$unwind: "$ingredientsParts"
},
{
"$group": {
_id: "$id",
name: {
$first: "$name"
},
ingredientsParts: {
$push: {
v: "$ingredientsParts.v",
id: {
$toInt: "$ingredientsParts.k"
}
}
}
}
},
{
"$lookup": {
"from": "ingredients",
"localField": "ingredientsParts.id",
"foreignField": "id",
"as": "ingredients"
}
},
{
$unwind: "$ingredients"
},
{
"$addFields": {
"ingredientsPart": {
"$filter": {
input: "$ingredientsParts",
as: "item",
cond: {
$eq: [
"$$item.id",
"$ingredients.id"
]
}
}
}
}
},
{
$project: {
ingredients: 1,
ingredientsPart: {
"$arrayElemAt": [
"$ingredientsPart",
0
]
},
name: 1
}
},
{
"$addFields": {
units: {
k: "$ingredients.name",
v: {
"$concat": [
{
$toString: "$ingredientsPart.v"
},
" ",
"$ingredients.unit"
]
}
}
}
},
{
$group: {
_id: "$_id",
name: {
$first: "$name"
},
units: {
$push: "$units"
}
}
},
{
"$addFields": {
"data": {
"$arrayToObject": "$units"
}
}
},
{
"$addFields": {
"data.id": "$_id",
"data.name": "$name"
}
},
{
"$replaceRoot": {
"newRoot": "$data"
}
}
])
You can see it works here
As rickhg12hs said, it can be modeled better.
We have a requirement to show nodes and edges graph in our Angular application and we chose to do it in cytoscape over high charts/amCharts/D3. Cytoscape is faster in loading and is the only library to handle 1000s of nodes that we have. Others break or lags.
We downloaded cytoscape app and were able to see a layout 'Edge weighted spring embedded'. It shows our interconnected nodes in a overall globe-like layout.
Now I want the same in cytoscape js and looks like we only have handful of layouts in https://js.cytoscape.org/
Does this layout possible in cytoscape js? How to achieve this? (Currently using fcose layout but we really like the globe look that 'Edge weighted spring embedded layout brings.
EDIT:
Here is another example: I want to achieve this layout in cytoscape.js.
What layout I should follow? Or is this something not available in js and only available in desktop App
There are three options I think:
The Compound Spring Embedder layout cose
The Compound Spring Embedder layout by Bilkent (for an enhanced compound node placement) cose-bilkent
The Constraint-Based Layout cola.js
They all use some sort of force directed layout, I think you should give them a try and use the one most fitting to your needs. There are many parameters you can set for each layout, so take a closer look at them too. For example, if you set infinite to true in the cola.js layout, you will see that you can move the nodes around and see the layout force them back to or to a fitting position:
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
autounselectify: true,
boxSelectionEnabled: false,
layout: {
name: "cola",
infinite: true,
fit: false
},
style: [{
selector: "node",
css: {
"background-color": "#f92411"
}
},
{
selector: "edge",
css: {
"line-color": "#f92411"
}
}
],
elements: {
nodes: [{
data: {
id: "1",
label: "P"
}
},
{
data: {
id: "2",
label: "sucrose phosphate phosphatase"
}
},
{
data: {
id: "4",
label: "sucrose 6-phosphate"
}
},
{
data: {
id: "6",
label: "sucrose"
}
},
{
data: {
id: "8",
label: "invertase"
}
},
{
data: {
id: "10",
label: "fructose"
}
},
{
data: {
id: "12",
label: "fructokinase"
}
},
{
data: {
id: "14",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "20",
label: "phosphoglucose isomerase"
}
},
{
data: {
id: "22",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "28",
label: "glucose"
}
},
{
data: {
id: "30",
label: "hexokinase"
}
},
{
data: {
id: "33",
label: "sucrose synthase"
}
},
{
data: {
id: "36",
label: "UDP - glucose"
}
},
{
data: {
id: "38",
label: "sucrose phosphate synthase"
}
},
{
data: {
id: "41",
label: "UDP"
}
},
{
data: {
id: "44",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "46",
label: "ATP"
}
},
{
data: {
id: "47",
label: "ATP"
}
},
{
data: {
id: "52",
label: "ATP"
}
},
{
data: {
id: "57",
label: "ADP"
}
},
{
data: {
id: "66",
label: "PP"
}
},
{
data: {
id: "71",
label: "UTP"
}
},
{
data: {
id: "76",
label: "UDP glucose pyrophosphorylase"
}
},
{
data: {
id: "80",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "86",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "89",
label: "G1P transporter"
}
},
{
data: {
id: "90",
label: "P"
}
},
{
data: {
id: "95",
label: "P"
}
},
{
data: {
id: "102",
label: "P"
}
},
{
data: {
id: "103",
label: "P"
}
},
{
data: {
id: "104",
label: "G6P transporter"
}
},
{
data: {
id: "109",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "115",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "121",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "128",
label: "ADPglucose pyrophosphorylase (pAGPase)"
}
},
{
data: {
id: "130",
label: "ADP - glucose"
}
},
{
data: {
id: "136",
label: "PP"
}
},
{
data: {
id: "141",
label: "ATP"
}
},
{
data: {
id: "148",
label: "inorganic diphosphatase"
}
},
{
data: {
id: "149",
label: "P"
}
},
{
data: {
id: "156",
label: "phosphate transporter"
}
},
{
data: {
id: "158",
label: "P"
}
},
{
data: {
id: "164",
label: "starch synthase (simpl.)"
}
},
{
data: {
id: "166",
label: "ADP"
}
},
{
data: {
id: "172",
label: "starch"
}
},
{
data: {
id: "178",
label: "ATP/ADP transporter"
}
},
{
data: {
id: "179",
label: "ADP"
}
},
{
data: {
id: "184",
label: "ADP"
}
},
{
data: {
id: "189",
label: "ATP"
}
}
],
edges: [{
data: {
source: "2",
target: "1"
}
},
{
data: {
source: "4",
target: "2"
}
},
{
data: {
source: "2",
target: "6"
}
},
{
data: {
source: "6",
target: "8"
}
},
{
data: {
source: "8",
target: "10"
}
},
{
data: {
source: "12",
target: "14"
}
},
{
data: {
source: "14",
target: "20"
}
},
{
data: {
source: "20",
target: "22"
}
},
{
data: {
source: "8",
target: "28"
}
},
{
data: {
source: "28",
target: "30"
}
},
{
data: {
source: "30",
target: "22"
}
},
{
data: {
source: "6",
target: "33"
}
},
{
data: {
source: "33",
target: "10"
}
},
{
data: {
source: "33",
target: "36"
}
},
{
data: {
source: "36",
target: "38"
}
},
{
data: {
source: "38",
target: "4"
}
},
{
data: {
source: "38",
target: "41"
}
},
{
data: {
source: "41",
target: "33"
}
},
{
data: {
source: "44",
target: "38"
}
},
{
data: {
source: "52",
target: "12"
}
},
{
data: {
source: "12",
target: "57"
}
},
{
data: {
source: "46",
target: "30"
}
},
{
data: {
source: "30",
target: "47"
}
},
{
data: {
source: "71",
target: "76"
}
},
{
data: {
source: "76",
target: "66"
}
},
{
data: {
source: "76",
target: "36"
}
},
{
data: {
source: "80",
target: "76"
}
},
{
data: {
source: "22",
target: "86"
}
},
{
data: {
source: "86",
target: "80"
}
},
{
data: {
source: "95",
target: "89"
}
},
{
data: {
source: "89",
target: "90"
}
},
{
data: {
source: "102",
target: "104"
}
},
{
data: {
source: "80",
target: "89"
}
},
{
data: {
source: "104",
target: "109"
}
},
{
data: {
source: "115",
target: "109"
}
},
{
data: {
source: "121",
target: "89"
}
},
{
data: {
source: "121",
target: "115"
}
},
{
data: {
source: "121",
target: "128"
}
},
{
data: {
source: "128",
target: "130"
}
},
{
data: {
source: "141",
target: "128"
}
},
{
data: {
source: "128",
target: "136"
}
},
{
data: {
source: "136",
target: "148"
}
},
{
data: {
source: "148",
target: "149"
}
},
{
data: {
source: "149",
target: "156"
}
},
{
data: {
source: "156",
target: "158"
}
},
{
data: {
source: "130",
target: "164"
}
},
{
data: {
source: "164",
target: "166"
}
},
{
data: {
source: "178",
target: "179"
}
},
{
data: {
source: "184",
target: "178"
}
},
{
data: {
source: "178",
target: "189"
}
},
{
data: {
source: "141",
target: "178"
}
},
{
data: {
source: "104",
target: "103"
}
},
{
data: {
source: "10",
target: "12"
}
},
{
data: {
source: "164",
target: "172"
}
},
{
data: {
source: "22",
target: "104"
}
}
]
}
}));
cy.unbind("tapend");
cy.bind("tapend", "node", function() {
cy.animate({
fit: {
eles: cy.elements(),
padding: 20
},
center: {
eles: cy.elements()
}
}, {
duration: 500
});
});
});
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
<!DOCTYPE>
<html>
<head>
<title>cytoscape-cola.js demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/webcola/WebCola/cola.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cola#2.3.0/cytoscape-cola.min.js"></script>
</head>
<body>
<h1>cytoscape-cola demo</h1>
<div id="cy"></div>
</body>
</html>
You can try "Euler" layout, it might give the same expected layout that you wanted. It is euler.js. I am using this layout for my own data set and is giving similar layout that you have shown above.
How to write schema for this kind of response.
{
"adult": false,
"backdrop_path": "/dnaitaoCh8MftfYEVnprcuYExZp.jpg",
"belongs_to_collection": {
"id": 256322,
"name": "The Purge Collection",
"poster_path": "/nP3c8mTSxlis4vfg0UjlkK8LRG9.jpg",
"backdrop_path": "/quFWGOA4I5KCTsyDbvLh6PHNZwv.jpg"
},
"budget": 13000000,
"genres": [
{
"id": 28,
"name": "Action"
},
{
"id": 27,
"name": "Horror"
},
{
"id": 878,
"name": "Science Fiction"
},
{
"id": 53,
"name": "Thriller"
}
]
}
const typeDefs = `
type BelongsToCollectionType {
id: ID!
name: String
poster_path: String
backdrop_path: String
}
type GenreType {
id: ID!
name: String
}
type SomeType {
adult: Boolean
backdrop_path: String
belongs_to_collection: BelongsToCollectionType
budget: Int
genres: [GenreType]!
}
`;
Soon after I asked this question I figured it out. Here is the schema:
const MovieType = new GraphQLObjectType({
name: 'Movie',
fields: () => ({
id: { type: GraphQLString },
adult: { type: GraphQLBoolean },
backdrop_path: { type: GraphQLString },
belongs_to_collection: { type: BelongsToCollection },
budget: { type: GraphQLInt },
overview: { type: GraphQLString },
popularity: { type: GraphQLInt },
poster_path: { type: GraphQLString },
production_companies: {
type: new GraphQLList(CompaniesType)
},
genres: {
type: new GraphQLList(GenreType)
},
release_date: { type: GraphQLString },
tagline: { type: GraphQLString },
title: { type: GraphQLString },
vote_average: { type: GraphQLInt },
vote_count: { type: GraphQLInt }
})
});
const CompaniesType = new GraphQLObjectType({
name: 'ProductionCompanies',
fields: {
id: { type: GraphQLInt },
name: { type: GraphQLString },
logo_path: { type: GraphQLString },
original_country: { type: GraphQLString }
}
});
const GenreType = new GraphQLObjectType({
name: 'Genre',
fields: () => ({
id: { type: GraphQLInt },
name: { type: GraphQLString }
})
})
const BelongsToCollection = new GraphQLObjectType({
name: 'BelongsToCollection',
fields: () => ({
id: { type: GraphQLInt },
name: { type: GraphQLString },
poster_path: { type: GraphQLString },
backdrop_path: { type: GraphQLString }
})
});
I have a requirement to create a tree grid which has unknown number of columns and data which gets rendered on click on a button. I have following code for the same.
//Model
Ext.define('SM.model.DynamicTreeModel', {
extend: 'Ext.data.Model'
});
//Store
Ext.define('SM.store.DynamicTreeStore',{
extend:'Ext.data.TreeStore',
model:'SM.DynamicTreeModel',
root: {
expanded: true
},
proxy: {
type: 'ajax',
url: 'TGData1.json',
reader: {
type: 'json',
root: 'children'
}
},
autoLoad: true
});
Ext.define('SM.view.compareScenario.DynamicTree', {
extend: 'Ext.tree.Panel',
alias: 'widget.DynamicTree',
frame: true,
columnLines: true,
autoLoad: false,
initComponent: function(){
var config = {
columns: [],
rowNumberer: false
};
Ext.apply(this, config);
Ext.apply(this.initialConfig, config);
this.callParent(arguments);
},
storeLoad: function(){
var columns = [];
Ext.each(this.store.proxy.reader.jsonData.columns, function(column){
columns.push(column);
});
this.reconfigure(this.store, columns);
this.store.getRootNode(this.store.getRootNode);
},
onRender: function(ct, position){
SM.view.compareScenario.DynamicTree.superclass.onRender.call(this, ct, position);
this.store.load({
scope: this,
callback: function(records, operation, success) {
this.storeLoad();
}
});
}
});
var influencesTree = {
xtype: 'DynamicTree',
id: 'influencesTree',
pading: '5',
region: 'south',
height: '70%',
collapsible: true,
rootVisible: false,
store: 'DynamicTreeStore'
};
The json file is as follows:
{
"metaData": {
"fields": [
{"name":"0", "type":"string"},
{"name":"1", "type":"string"},
{"name":"2", "type":"string"}
]
},
"columns" : [
{
"xtype":"treecolumn", //this is so we know which column will show the tree
"text":"Override Type",
"flex":"2",
"sortable":"true",
"dataIndex":"0"
},
{
"text":"Scenario 1",
"dataIndex":"1"
},
{
"text":"Copied Scenario",
"dataIndex":"2"
}
]
,
"text": ".",
"children": [{
"0":"CFO",
"1":"15",
"2":"16",
"children":[{
"0":"AW",
"1": "5",
"2": "5",
"leaf": "true",
},
{
"0":"AV",
"1":"10",
"2":"11",
"leaf": "true",
}
]
}
]
}
The tree renders, but the child nodes cannot be expanded as the + icon is not shown. Instead of + icon, a checkbox is rendered.
Any help/suggestions for the same will be highly appreciated.
Thanks,
Shalini
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.dd.*']);
Ext.onReady(function () {
var myData = [{
name: "Rec 0",
type: "0"
}, {
name: "Rec 1",
type: "1"
}, {
name: "Rec 2",
type: "2"
}, {
name: "Rec 3",
type: "3"
}, {
name: "Rec 4",
type: "4"
}, {
name: "Rec 5",
type: "5"
}, {
name: "Rec 6",
type: "6"
}, {
name: "Rec 7",
type: "7"
}, {
name: "Rec 8",
type: "8"
}, {
name: "Rec 9",
type: "9"
}];
// create the data store
var firstGridStore = Ext.create('Ext.data.Store', {
model: 'Apps.demo.model.Resource',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/echo/json/',
actionMethods: {
read: 'POST'
},
extraParams: {
json: Ext.JSON.encode(myData)
},
delay: 0
}
});
// Column Model shortcut array
var columns = [{
text: "Name",
flex: 1,
sortable: true,
dataIndex: 'name'
}, {
text: "Type",
width: 70,
sortable: true,
dataIndex: 'type'
}];
// declare the source Grid
var firstGrid = Ext.create('Ext.grid.Panel', {
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
ddGroup: 'selDD'
},
listeners: {
drop: function (node, data, dropRec, dropPosition) {
}
}
},
store: firstGridStore,
columns: columns,
stripeRows: true,
title: 'First Grid',
margins: '0 2 0 0'
});
// create the destination Grid
var secondTree = Ext.create('Apps.demo.view.TreeGrid', {
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
ddGroup: 'selDD'
},
listeners: {
beforedrop: function (node, data) {
data.records[0].set('leaf', false);
data.records[0].set('checked', null);
},
drop: function (node, data, dropRec, dropPosition) {
firstGrid.store.remove(data.records[0]);
}
}
}
});
var displayPanel = Ext.create('Ext.Panel', {
width: 650,
height: 300,
layout: {
type: 'hbox',
align: 'stretch',
padding: 5
},
renderTo: 'panel',
defaults: {
flex: 1
}, //auto stretch
items: [
firstGrid,
secondTree],
dockedItems: {
xtype: 'toolbar',
dock: 'bottom',
items: ['->', // Fill
{
text: 'Reset both components',
handler: function () {
firstGridStore.loadData(myData);
secondTreeStore.removeAll();
}
}]
}
});
});
var response = Ext.JSON.encode({
"children": [{
"itemId": 171,
"type": "comedy",
"name": "All the way",
"children": [{
"leaf": true,
"itemId": 171,
"type": "actor",
"name": "Rowan Atkinson"
}],
}, {
"itemId": 11,
"type": "fantasy",
"name": "I love You",
"children": [{
"itemId": 11,
"leaf": true,
"type": "actor",
"name": "Rajan",
}]
}, {
"itemId": 173,
"type": "Action",
"name": "Fast and Furious",
"children": [{
"itemId": 174,
"type": "actor",
"name": "Dwayne Johnson",
"children": [{
"leaf": true,
"itemId": 175,
"type": "wrestler",
"name": "The Rock"
}]
}]
}]
});
Ext.define('Apps.demo.model.Resource', {
extend: 'Ext.data.Model',
fields: [{
name: "name",
type: "string"
}, {
name: "type",
type: "string"
}]
});
Ext.define('Apps.demo.view.TreeGrid', {
extend: 'Ext.tree.Panel',
title: 'Demo',
height: 300,
rootVisible: true,
singleExpand: true,
initComponent: function () {
Ext.apply(this, {
store: new Ext.data.TreeStore({
model: 'Apps.demo.model.Resource',
"root": {
"name": "",
"type": "",
"expanded": "true"
},
proxy: {
type: 'ajax',
url: '/echo/json/',
actionMethods: {
read: 'POST'
},
extraParams: {
json: response
},
delay: 0
}
}),
listeners: {
'beforeiteminsert' : function(obj, node) {
console.log(node);
}
},
columns: [{
xtype: 'treecolumn',
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Type',
dataIndex: 'type'
}]
});
this.callParent();
}
});
var grid = Ext.create('Apps.demo.view.TreeGrid');
Please check this code .It might not give u the proper answer but will surely give u the hint how to achieve the output.