How to get only specific nested object from MongoDB collection where uuid is used as key - mongodb

I only want this matched object in query result, by querying uuid "630c260e333c41549c43cae5f8e626d5":
{
"enableAnnotations": false,
"enableMultipleFilesUpload": true,
"enableWorkflows": true,
"formSectionID": "a9bcde7f8fc14e519965a655d9574fb7",
"isThumbnailField": false,
"label": "WD multi upload Ttl in Dup Section DW",
"publishToFolder": false,
"publishWhenApproved": false,
"type": "upload",
"uuid": "630c260e333c41549c43cae5f8e626d5"
}
from the following Collection document:
[{
"_id": "07672b703cc44ce6887159984911dd6e",
"createTime": "2022-06-21T12:08:00Z",
"creator": "75e5d59fa1be0f932bff8407536730d0",
"defination": {
"fields": {
"a9bcde7f8fc14e519965a655d9574fb7": [
{
"enableAnnotations": false,
"enableMultipleFilesUpload": true,
"enableWorkflows": true,
"formSectionID": "a9bcde7f8fc14e519965a655d9574fb7",
"isThumbnailField": false,
"label": "WD multi upload Ttl in Dup Section DW",
"publishToFolder": false,
"publishWhenApproved": false,
"type": "upload",
"uuid": "630c260e333c41549c43cae5f8e626d5"
},
{
"enableAnnotations": false,
"enableMultipleFilesUpload": false,
"formSectionID": "a9bcde7f8fc14e519965a655d9574fb7",
"isThumbnailField": false,
"label": "WD single upload in Dup section DW",
"publishToFolder": false,
"type": "upload",
"uuid": "1aecb33709434d9b9a0cb455c67e2295"
}
],
"eda3ce9883a14b948eae5b053f720227": [
{
"enableAnnotations": false,
"enableMultipleFilesUpload": true,
"enableWorkflows": true,
"formSectionID": "eda3ce9883a14b948eae5b053f720227",
"isThumbnailField": false,
"label": "WD upload multi",
"publishToFolder": false,
"publishWhenApproved": false,
"type": "upload",
"uuid": "e88a097621cc44c4bb440902006f5a12"
},
{
"formSectionID": "eda3ce9883a14b948eae5b053f720227",
"label": "WD Txt Fld Ttl",
"type": "text",
"uuid": "e1bf361509364718b9d52e65cbc292de",
},
{
"enableAnnotations": false,
"enableMultipleFilesUpload": true,
"enableWorkflows": true,
"formSectionID": "eda3ce9883a14b948eae5b053f720227",
"isThumbnailField": false,
"label": "WD 2nd-multi-upload",
"publishToFolder": false,
"publishWhenApproved": false,
"type": "upload",
"uuid": "fbee1d1adf224712a90f3f37b8395aa0"
},
{
"enableAnnotations": true,
"enableMultipleFilesUpload": false,
"formSectionID": "eda3ce9883a14b948eae5b053f720227",
"isThumbnailField": false,
"label": "WD single upload Ttl DW",
"publishToFolder": false,
"type": "upload",
"uuid": "5504ce66d1bc4f659eefed4df4e73b99",
}
]
},
"sections": {
"291b58eddee04a05bd8e7d80d99241b9": [
{
"uuid": "eda3ce9883a14b948eae5b053f720227"
},
{
"uuid": "a9bcde7f8fc14e519965a655d9574fb7"
}
]
},
"tabs": [
{
"uuid": "291b58eddee04a05bd8e7d80d99241b9"
}
]
}
}]
After some research, I used the query: (by referring how to select value if key is uuid in mongodb)
db.collection.aggregate([
{
"$set": {
"fields": {
"$objectToArray": "$defination.fields"
}
}
},
{
"$unwind": "$fields"
},
{
"$match": {
"fields.v.uuid": "630c260e333c41549c43cae5f8e626d5",
"fields.v.enableWorkflows": true,
"fields.v.enableMultipleFilesUpload": true,
"fields.v.type": "upload"
}
},
{
"$group": {
"_id": "$_id",
"fields": {
"$push": "$fields"
}
}
},
{
"$set": {
"fields": {
"$arrayToObject": "$fields"
}
}
}
])
and I got the result:
[
{
"_id": "07672b703cc44ce6887159984911dd6e",
"fields": {
"a9bcde7f8fc14e519965a655d9574fb7": [
{
"enableAnnotations": false,
"enableMultipleFilesUpload": true,
"enableWorkflows": true,
"formSectionID": "a9bcde7f8fc14e519965a655d9574fb7",
"isThumbnailField": false,
"label": "WD multi upload Ttl in Dup Section DW",
"publishToFolder": false,
"publishWhenApproved": false,
"type": "upload",
"uuid": "630c260e333c41549c43cae5f8e626d5"
},
{
"enableAnnotations": false,
"enableMultipleFilesUpload": false,
"formSectionID": "a9bcde7f8fc14e519965a655d9574fb7",
"isThumbnailField": false,
"label": "WD single upload in Dup section DW",
"publishToFolder": false,
"type": "upload",
"uuid": "1aecb33709434d9b9a0cb455c67e2295"
}
]
}
}
]
But it contains extra sibling objects.
I tried the answer from post but it doesn't work: How can I get only specific object from nested array mongodb

One option to drill down is using $reduce with $filter, but first we need known keys, hence the $objectToArray which you already have:
db.collection.aggregate([
{$project: {fields: {$objectToArray: "$defination.fields"}}},
{$project: {res: {
$first: {
$reduce: {
input: "$fields",
initialValue: [],
in: {$concatArrays: [
"$$value",
{$filter: {
input: "$$this.v",
as: "inner",
cond: {
$eq: [
"$$inner.uuid",
"630c260e333c41549c43cae5f8e626d5"
]
}
}
}
]
}
}
}
}
}
},
{$replaceRoot: {newRoot: {$ifNull: ["$res", {}]}}}
])
See how it works on the playground example

Related

MongoDB sort by multiple fields on boolean type

First of all i need "isFavourite": true then "isReadByPro": false and then updatedAt:-1.
I tried below way but not working.
{ $sort: { updatedAt: -1 } },
{ $sort: { isReadByPro: 1 } },
{ $sort: { isFavourite: -1 } },
[
{
"_id": "628c8378c92d4b969cf4b53b",
"post": {
"title": "project 94608"
},
"isFavourite": true,
"isReadByPro": true,
"updatedAt": "2022-06-06T10:34:05.776Z"
},
{
"_id": "628f507192034120c7fc261a",
"post": {
"title": "your payment test 1"
},
"isFavourite": true,
"isReadByPro": true,
"updatedAt": "2022-05-27T10:39:16.493Z"
},
{
"_id": "628f50a792034120c7fc2681",
"post": {
"title": "your payment test 3"
},
"isFavourite": true,
"isReadByPro": true,
"updatedAt": "2022-05-27T08:42:48.403Z"
},
{
"_id": "628c76840ffe2cd088654d50",
"post": {
"title": "showcase 1"
},
"isFavourite": false,
"isReadByPro": true,
"updatedAt": "2022-05-24T06:10:38.364Z"
},
{
"_id": "628c780a0ffe2cd088654e21",
"post": {
"title": "project 1 test"
},
"isFavourite": false,
"isReadByPro": true,
"updatedAt": "2022-05-27T06:30:54.058Z"
},
{
"_id": "628c79cb5b4b0ee6020482df",
"post": {
"title": "project 2 test"
},
"isFavourite": false,
"isReadByPro": true,
"updatedAt": "2022-05-27T06:30:54.058Z"
}
]
In order to sort by multiple fields, they should be on the same sorting object. The order of them is according to priority. This data is sorted first by isFavourite, then, all the documents with the same isFavourite value will be sorted between them by isReadByPro and so on.
{ $sort: {isFavourite: -1, isReadByPro: 1, updatedAt: -1} }

Name relationship link between two different types in Apache Atlas

I am trying to name relationship link (by using attributeDefs) between two different types. The relationship is now registered in Atlas and definition fetch results as below:
{
"category": "RELATIONSHIP",
"guid": "9b1059c3-8707-46db-ae3c-e8d1b4ef6333",
"createdBy": "admin",
"updatedBy": "admin",
"createTime": 1625233869809,
"updateTime": 1625496519772,
"version": 6,
"name": "field_assignment",
"description": "someDescription.",
"typeVersion": "1.0",
"attributeDefs": [
{
"name": "LinkInformation",
"typeName": "string",
"isOptional": true,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1
}
],
"relationshipCategory": "ASSOCIATION",
"propagateTags": "NONE",
"endDef1": {
"type": "custom_dataset",
"name": "fields",
"isContainer": false,
"cardinality": "SET",
"isLegacyAttribute": false
},
"endDef2": {
"type": "custom_field",
"name": "datasets",
"isContainer": false,
"cardinality": "SET",
"isLegacyAttribute": false
}
}
Now, I am trying to create a relationship between two types while defining an Entity for either type like
{
"entities": [
{
"typeName": "custom_field",
"createdBy": "admin",
"guid": -1000,
"attributes": {
"name": "type",
"datasets": [
{
"guid": "-200",
"typeName": "custom_dataset"
}
]
},
"classifications": [],
}
],
"referredEntities": {
"-200": {
"guid": "-200",
"typeName": "custome_dataset",
"relationshipAttributes" : {"LinkInformation": "key"},
"attributes": {
"qualifiedName": "test"
}
}
}
}
Through, while executing this, I don't see any error and entities are created but LinkInformation is null by simply doing a search by GUID for entities.
...
"relationshipAttributes": {
"typeName": "field_assignment",
"attributes": {
"LinkInformation": null
}
}
...
I am not able to find a good documentation anywhere for this. Can anyone help?
Atlas relationship between existing entities can be created either using entity GUIDs or uniqueAttributes in end1 and end2 which can be qualifiedName or any other unique attribute .
Please do note that top level typeName is the relationship def typeName while typeName inside end1 and end2 is entity typeName.
In case of relationship between hive_table and hive_db the relationship def typeName is: hive_table_db
So, if you want to create a relationship between hive_table and hive_db, the request would be:
POST: /api/atlas/v2/relationship
{
"typeName": "hive_table_db",
"end1": {
"typeName": "hive_table",
"uniqueAttributes": {
"qualifiedName": "db.table#cluster"
}
},
"end2": {
"typeName": "hive_db",
"uniqueAttributes": {
"qualifiedName": "db#cluster"
}
}
}
For predefined Atlas types you can find the relationship typeName from its definition inside relationshipAttributeDefs field
GET: /api/atlas/v2/types/typedef/name/hive_db
Which gives the following response:
{
"category": "ENTITY",
"guid": "9b1059c3-8707-46db-ae3c-e8d1b4ef6333",
"createdBy": "root",
"updatedBy": "root",
"createTime": 1548175553859,
"updateTime": 1548175822249,
"version": 2,
"name": "hive_db",
"description": "hive_db",
"typeVersion": "1.2",
"serviceType": "hive",
"attributeDefs": [
{
"name": "clusterName",
"typeName": "string",
"isOptional": false,
"cardinality": "SINGLE",
"valuesMinCount": 1,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": true,
"includeInNotification": true,
"searchWeight": -1
},
{
"name": "location",
"typeName": "string",
"isOptional": true,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1
},
{
"name": "parameters",
"typeName": "map<string,string>",
"isOptional": true,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1
},
{
"name": "ownerType",
"typeName": "hive_principal_type",
"isOptional": true,
"cardinality": "SINGLE",
"valuesMinCount": 0,
"valuesMaxCount": 1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1
}
],
"superTypes": [
"Asset"
],
"subTypes": [],
"relationshipAttributeDefs": [
{
"name": "tables",
"typeName": "array<hive_table>",
"isOptional": true,
"cardinality": "SET",
"valuesMinCount": -1,
"valuesMaxCount": -1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1,
"constraints": [
{
"type": "ownedRef"
}
],
"relationshipTypeName": "hive_table_db",
"isLegacyAttribute": false
},
{
"name": "ddlQueries",
"typeName": "array<hive_db_ddl>",
"isOptional": true,
"cardinality": "SET",
"valuesMinCount": -1,
"valuesMaxCount": -1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1,
"constraints": [
{
"type": "ownedRef"
}
],
"relationshipTypeName": "hive_db_ddl_queries",
"isLegacyAttribute": false
},
{
"name": "meanings",
"typeName": "array<AtlasGlossaryTerm>",
"isOptional": true,
"cardinality": "SET",
"valuesMinCount": -1,
"valuesMaxCount": -1,
"isUnique": false,
"isIndexable": false,
"includeInNotification": false,
"searchWeight": -1,
"relationshipTypeName": "AtlasGlossarySemanticAssignment",
"isLegacyAttribute": false
}
]
}
Further, you need to make sure the typeName in end1 and end2 is as per the relationship def, which you can check in type definition:
GET: /api/atlas/v2/types/typedef/name/hive_table_db
{
"category": "RELATIONSHIP",
"guid": "9b1059c3-8707-46db-ae3c-e8d1b4ef6333",
"createdBy": "root",
"updatedBy": "root",
"createTime": 1548175553894,
"updateTime": 1548175553894,
"version": 1,
"name": "hive_table_db",
"description": "hive_table_db",
"typeVersion": "1.0",
"serviceType": "hive",
"attributeDefs": [],
"relationshipCategory": "COMPOSITION",
"propagateTags": "NONE",
"endDef1": {
"type": "hive_table",
"name": "db",
"isContainer": false,
"cardinality": "SINGLE",
"isLegacyAttribute": true
},
"endDef2": {
"type": "hive_db",
"name": "tables",
"isContainer": true,
"cardinality": "SET",
"isLegacyAttribute": false
}
}

Inserting data in private ipfs network from outside of server throws timeout error

I installed private ipfs network on my server and after that i tested it with entering a file and getting it which works perfectly,now when i try to follow the same steps from my local machine,getting data is working with the url - http://{server's ip}:8080/ipfs/{hash} but when i created api on Nodejs to insert data using url - http://{server's ip}:5001 then i am getting the error of timeout,though this api is working on deploying on server and changing the server's ip to localhost.
IPFS config is as follows -
{
"API": {
"HTTPHeaders": {
"Access-Control-Allow-Methods": [
"PUT",
"GET",
"POST"
],
"Access-Control-Allow-Origin": [
"*"
]
}
},
"Addresses": {
"API": "/ip4/0.0.0.0/tcp/5001",
"Announce": [],
"Gateway": "/ip4/0.0.0.0/tcp/8080",
"NoAnnounce": [],
"Swarm": [
"/ip4/0.0.0.0/tcp/4001",
"/ip6/::/tcp/4001"
]
},
"Bootstrap": [
"/ip4/{server's ip}/tcp/4001/ipfs/<peer identity hash of bootnode>"
],
"Datastore": {
"BloomFilterSize": 0,
"GCPeriod": "1h",
"HashOnRead": false,
"Spec": {
"mounts": [
{
"child": {
"path": "blocks",
"shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
"sync": true,
"type": "flatfs"
},
"mountpoint": "/blocks",
"prefix": "flatfs.datastore",
"type": "measure"
},
{
"child": {
"compression": "none",
"path": "datastore",
"type": "levelds"
},
"mountpoint": "/",
"prefix": "leveldb.datastore",
"type": "measure"
}
],
"type": "mount"
},
"StorageGCWatermark": 90,
"StorageMax": "10GB"
},
"Discovery": {
"MDNS": {
"Enabled": true,
"Interval": 10
}
},
"Experimental": {
"FilestoreEnabled": false,
"Libp2pStreamMounting": false,
"P2pHttpProxy": false,
"QUIC": false,
"ShardingEnabled": false,
"UrlstoreEnabled": false
},
"Gateway": {
"APICommands": [],
"HTTPHeaders": {
"Access-Control-Allow-Headers": [
"X-Requested-With",
"Range"
],
"Access-Control-Allow-Methods": [
"GET"
],
"Access-Control-Allow-Origin": [
"*"
]
},
"PathPrefixes": [],
"RootRedirect": "",
"Writable": false
},
"Identity": {
"PeerID": "<peer identity hash of bootnode>"
},
"Ipns": {
"RecordLifetime": "",
"RepublishPeriod": "",
"ResolveCacheSize": 128
},
"Mounts": {
"FuseAllowOther": false,
"IPFS": "/ipfs",
"IPNS": "/ipns"
},
"Pubsub": {
"DisableSigning": false,
"Router": "",
"StrictSignatureVerification": false
},
"Reprovider": {
"Interval": "12h",
"Strategy": "all"
},
"Routing": {
"Type": "dht"
},
"Swarm": {
"AddrFilters": null,
"ConnMgr": {
"GracePeriod": "20s",
"HighWater": 900,
"LowWater": 600,
"Type": "basic"
},
"DisableBandwidthMetrics": false,
"DisableNatPortMap": false,
"DisableRelay": false,
"EnableRelayHop": true
}
}

Filter out inner collection on mongodb/mongoose

Can you tell me how to filter out on videoDetails where vimeo_id==null? According to the below query, it retrieves all the data. i.e. including the none Vimeo videos. Here I have used Mongoose.
Data:
{
"_id": ObjectId("5b10e8c475356969da5f91b2"),
"playlists": [{
"listId": "5b26a1040c4ebb107f0038e5",
"title": "Featured Stories (copy)",
"playlist_item_count": 1,
"sortOrder": 1,
"_id": ObjectId("5b37adf40fc31552f9280603"),
"isPrimary": true,
"videoDetails": [{
"short_description": "",
"vimeo_id": null,
"title": "Managing-Time-Effectively-Section-4-Lecture-1-Questions-and-Answers.mp4",
"duration": 493,
"videoId": "5a3c2f03e338f91564000130",
"_id": ObjectId("5b37adf40fc31552f9280604"),
"accessLevel": "public"
}]
},
{
"listId": "5b375560d80ed51238004998",
"title": "Atv-test",
"playlist_item_count": 1,
"sortOrder": 1,
"_id": ObjectId("5b37adf40fc31552f9280601"),
"isPrimary": false,
"videoDetails": [{
"short_description": "When Alice’s husband arrives home to try and make amends it leaves her navigating a tricky situation.",
"vimeo_id": "277029143",
"title": "Love Is Blind",
"duration": 385,
"videoId": "5b375add2ef7c612f1002304",
"presentedBy": "CEO TEAM",
"_id": ObjectId("5b37adf40fc31552f9280602"),
"accessLevel": "public"
}]
}
],
"__v": 90
}
get
get(req) {
mongoose.connect(config.mongoConnectionUrl, { useMongoClient: true })
return Playlist
.findOne({})
.exec()
.then((playlist) => {
mongoose.disconnect()
return Promise.resolve({ error: false, playlist })
})
.catch((e) => {
mongoose.disconnect()
const err = prepareApiError(e)
return new api.ApiResponse({ error: true, reason: err.reason }, { "Content-Type": "application/json" }, err.errorCode)
})
},
You can try below aggregation
db.collection.aggregate([
{ "$project": {
"playlists": {
"$map": {
"input": "$playlists",
"as": "play",
"in": {
"listId": "$$play.listId",
"title": "$$play.title",
"playlist_item_count": "$$play.playlist_item_count",
"sortOrder": "$$play.sortOrder",
"_id": "$$play._id",
"isPrimary": "$$play.isPrimary",
"videoDetails": {
"$filter": {
"input": "$$play.videoDetails",
"as": "video",
"cond": { "$ne": ["$$video.vimeo_id", null] }
}
}
}
}
}
}}
])

Moogose append to the sub array document

I am having a problem with appending data into the sub document.
exports.appendfiles = function(req, res) {
project.findOneAndUpdate(
{
_id: req.body.id
},
{ $push:
{ 'files' : req.files }
},
{
safe: true,
upsert:true
},
function(err, data) {
console.log(err);
return res.send('ok');
}
);
};
This above code does append the data into the sub document, but however you can see the below output it appends a new item with a new index, which is not great. I kept my files model as files : Array any one can help? Much appreciated. the following json is what i have cut out from the document.
{
"buffer": null,
"truncated": false,
"size": 497328,
"extension": "csv",
"path": "uploads/dc45dfeb54c4be89968faa46aabeb114.csv",
"mimetype": "text/csv",
"encoding": "7bit",
"name": "dc45dfeb54c4be89968faa46aabeb114.csv",
"originalname": "obansocial2015-04-20 (7).csv",
"fieldname": "3"
},
{
"0": {
"buffer": null,
"truncated": false,
"size": 8855,
"extension": "html",
"path": "uploads/273bee3485fc564e80d80e92cef32215.html",
"mimetype": "text/html",
"encoding": "7bit",
"name": "273bee3485fc564e80d80e92cef32215.html",
"originalname": "Southern Stars Conference 2014.html",
"fieldname": "0"
},
"1": {
"buffer": null,
"truncated": false,
"size": 383631,
"extension": "mp4",
"path": "uploads/f32da61db7e8df6fccf97b65a788e39d.mp4",
"mimetype": "video/mp4",
"encoding": "7bit",
"name": "f32da61db7e8df6fccf97b65a788e39d.mp4",
"originalname": "video.mp4",
"fieldname": "1"
}
},
You are pushing an array into another, hence it is being nested.
If you want to append each item, use the $each operator:
project.findOneAndUpdate(
{
_id: req.body.id
},
{ $push:
{ 'files' : {$each: req.files} }
},
{
safe: true,
upsert:true
},
function(err, data) {
console.log(err);
return res.send('ok');
}
);