I have a MongoDB that is structured as below:
[
{
"subject_id": "1",
"name": "Maria",
"dob": "1/1/00",
"gender": "F",
"visits": {
"1/1/18": {
"date_entered": "1/2/18",
"entered_by": "Sally"
},
"1/2/18": {
"date_entered": "1/2/18",
"entered_by": "Tim",
}
},
"samples": {
"XXX123": {
"collected_by": "Sally",
"collection_date": "1/3/18"
}
}
},
{
"subject_id": "2",
"name": "Bob",
"dob": "1/2/00",
"gender": "M",
"visits": {
"1/3/18": {
"date_entered": "1/4/18",
"entered_by": "Tim"
}
},
"samples": {
"YYY456": {
"collected_by": "Sally",
"collection_date": "1/5/18"
},
"ZZZ789": {
"collected_by": "Tim",
"collection_date": "1/6/18"
},
"AAA123": {
"collected_by": "Sally",
"collection_date": "1/7/18"
}
}
}
]
If I wanted to query the database to find all samples collected by Sally or all visits entered by Tim, what would be the best way of doing that?
I'm new to MongoDB and my attempts with various regex's haven't produced results. Any advice would be greatly appreciated.
I first used project on the required fields to use objectToArray followed by unwind to create separate records for array created in project.
The results are then filtered using match.
This works for the data provided in the question -
db.so.aggregate([
{$project: {visits: {$objectToArray: "$visits"}, samples: {$objectToArray: "$samples"}}},
{$unwind: "$visits"},
{$unwind: "$samples"},
{ $match: {
$or : [
{ "visits.v.entered_by" : "Tim" },
{ "samples.v.collected_by" : "Sally" }
]
}
}
])
Related
I'm trying to merge subdocument values into a collection, but I can't seem to find a way to do that. I have the following collection in MongoDB 4.0:
[{
"_id": "603f8c970f25800300a6c16e",
"Hash": "vkqsgIPmB4/am4KJkERghDmmCUXEZjrGQxdCF3Fll2brR0YxJSXeTg==",
"Components": [
{
"FieldA": "A-1",
"FieldB": "B-1"
},
{
"FieldA": "A-2",
"FieldB": "B-2"
}
]
},
{
"_id": "609f8c970f25800300a7c16e",
"Hash": "vkqsgIPmB4/am4KJkERghDmmCUXEZjrGQxdCF3Fll2brR0sddggdTs==",
"Components": [
{
"FieldA": "A-3",
"FieldB": "B-3"
},
{
"FieldA": "A-4",
"FieldB": "B-4"
}
]
}]
From this collection I would like to get the following result, where the id would be fed by the value of the main document, and the other fields would be fed by the subdocuments.
[
{
"_id":"603f8c970f25800300a6c16e",
"FieldA":"A-1",
"FieldB":"B-1"
},
{
"_id":"603f8c970f25800300a6c16e",
"FieldA":"A-2",
"FieldB":"B-2"
},
{
"_id":"609f8c970f25800300a7c16e",
"FieldA":"A-3",
"FieldB":"B-3"
},
{
"_id":"609f8c970f25800300a7c16e",
"FieldA":"A-4",
"FieldB":"B-4"
}
]
Thanks in advance!
You can do it like this:
$unwind - to unwind Components array
$project - to project data in the required format
db.collection.aggregate([
{
"$unwind": "$Components"
},
{
"$project": {
"FieldA": "$Components.FieldA",
"FieldB": "$Components.FieldB"
}
}
])
Working example
I have an 'users' collection. I store id's of users I follow in 'following' field.
{
"_id": {
"$oid": "5eab360253ec352e3cc791d6"
},
"email": "koray#gmail.com",
"password": "81dc9bdb52d04dc20036dbd8313ed055",
"following": ["5ea8879dfc286e1154a866cb", "5ea8879dfc286e1154a866c"],
"posts": [{
"head": "deneme header",
"body": "deneme body",
"is_private": false
}]
}
I want to get posts of users I follow as well as posts belogs to me but can't manage to pull it off.
You can use $lookup with custom pipeline and fetch documents from the same collection:
db.collection.aggregate([
{ $match: { _id: "5eab360253ec352e3cc791d6" } },
{
$lookup: {
from: "collection",
let: { following_users: "$following" },
pipeline: [
{ $match: { $expr: { $in: [ "$_id", "$$following_users" ] } } },
{ $project: { posts: 1 } }
],
as: "following_posts"
}
}
])
Mongo Playground
I'm trying to get my mocked JSON data via GraphQL in Gatsby. The response shows the correct data, but also two null objects as well. Why is it happening?
I'm using the gatsby-transformer.json plugin to query my data and gatsby-source-filesystem to point the transformer to my json files.
categories.json
the mock file I'm trying to get to work :)
{
"categories": [
{
"title": "DEZERTY",
"path": "/dezerty",
"categoryItems": [
{
"categoryName": "CUKRIKY",
"image": "../../../../static/img/dessertcategories/cukriky.jpg"
},
{
"categoryName": "NAHODNE",
"image": "../../../../static/img/dessertcategories/nahodne.jpg"
},
]
},
{
"title": "CANDY BAR",
"path": "/candy-bar",
"categoryItems": [
{
"categoryName": "CHEESECAKY",
"image": "../../../../static/img/dessertcategories/cheesecaky.jpg"
},
{
"categoryName": "BEZLEPKOVÉ TORTY",
"image": "../../../../static/img/dessertcategories/bezlepkove-torty.jpg"
},
]
}
]
}
GraphQL query in GraphiQL
query Collections {
allMockJson {
edges {
node {
categories {
categoryItems {
categoryName
image
}
title
path
}
}
}
}
}
And the response GraphiQL gives me
{
"data": {
"allMockJson": {
"edges": [
{
"node": {
"categories": null
}
},
{
"node": {
"categories": null
}
},
{
"node": {
"categories": [
{
"categoryItems": [
{
"categoryName": "CHEESECAKY",
"image": "../../../../static/img/dessertcategories/cheesecaky.jpg"
},
{
"categoryName": "BEZLEPKOVÉ TORTY",
"image": "../../../../static/img/dessertcategories/bezlepkove-torty.jpg"
}
],
"title": "DEZERTY",
"path": "/dezerty"
},
{
"categoryItems": [
{
"categoryName": "CUKRIKY",
"image": "../../../../static/img/dessertcategories/CUKRIKY.jpg"
},
{
"categoryName": "NAHODNE",
"image": "../../../../static/img/dessertcategories/NAHODNE.jpg"
}
],
"title": "CANDY BAR",
"path": "/candy-bar"
}
]
}
}
]
}
}
}
I expected only to get the DEZERTY and CANDY BAR sections. Why are there null categories and how do I fix it?
Thanks in advance
Your JSON contains syntax errors in the objects DEZERTY and CANDY BAR. It silently fails without telling you. Try this json linter.
Error: Parse error on line 12: },
Error: Parse error on line 25: },
Try again. Your query should work now.
You should look into an IDE that highlights these types of errors and saves you time and frustration.
Here is the sample JSON
Sample JSON:
[
{
"_id": "123456789",
"YEAR": "2019",
"VERSION": "2019.Version",
"QUESTION_GROUPS": [
{
"QUESTIONS": [
{
"QUESTION_NAME": "STATE_CODE",
"QUESTION_VALUE": "MH"
},
{
"QUESTION_NAME": "COUNTY_NAME",
"QUESTION_VALUE": "IN"
}
]
},
{
"QUESTIONS": [
{
"QUESTION_NAME": "STATE_CODE",
"QUESTION_VALUE": "UP"
},
{
"QUESTION_NAME": "COUNTY_NAME",
"QUESTION_VALUE": "IN"
}
]
}
]
}
]
Query that am using :
db.collection.find({},
{
"QUESTION_GROUPS.QUESTIONS.QUESTION_NAME": "STATE_CODE"
})
My requirement is retrive all QUESTION_VALUE whose QUESTION_NAME is equals to STATE_CODE.
Thanks in Advance.
If I get you well, What you are trying to do is something like:
db.collection.find(
{
"QUESTION_GROUPS.QUESTIONS.QUESTION_NAME": "STATE_CODE"
},
{
"QUESTION_GROUPS.QUESTIONS.QUESTION_VALUE": 1
})
Attention: you will get ALL the "QUESTION_VALUE" for ANY document which has a QUESTION_GROUPS.QUESTIONS.QUESTION_NAME with that value.
Attention 2: You will get also the _Id. It is by default.
In case you would like to skip those issues, you may need to use Aggregations, and unwind the "QUESTION_GROUPS"-> "QUESTIONS". This way you can skip both the irrelevant results, and the _id field.
It sounds like you want to unwind the arrays and grab only the question values back
Try this
db.collection.aggregate([
{
$unwind: "$QUESTION_GROUPS"
},
{
$unwind: "$QUESTION_GROUPS.QUESTIONS"
},
{
$match: {
"QUESTION_GROUPS.QUESTIONS.QUESTION_NAME": "STATE_CODE"
}
},
{
$project: {
"QUESTION_GROUPS.QUESTIONS.QUESTION_VALUE": 1
}
}
])
"LOTGraphData": [
{
buildUnits:"1"
ScheduledUnits:2"
prodGroupId:"9288"
},
{
buildUnits:"1"
ScheduledUnits:2"
prodGroupId:"9289"
},
{
buildUnits:"1"
ScheduledUnits:2"
prodGroupId:"9280"
}
]
}
This is the end of JSON file.
You have to separate your key/value pairs by commas. And (as per your confirmation), the keys have to be wrapped in quotes. So the final result will look like:
"LOTGraphData": [
{
"buildUnits": "1",
"ScheduledUnits": "2",
"prodGroupId": "9288"
},
{
"buildUnits": "1",
"ScheduledUnits": "2",
"prodGroupId": "9289"
},
{
"buildUnits": "1",
"ScheduledUnits": "2",
"prodGroupId": "9280"
}
]