Get Array element from JSON array from mongodb document - json

{
"employees" : [
{
"name" : "XXX",
"id" : "1",
"Salary" : [
{
"Month" : "XXXX",
"Amount" : "XXXX",
},
{
"Month" : "XXXX",
"Amount" : "XXXX",
},
{
"Month" : "XXXX",
"Amount" : "XXXX",
}
]
},
{
"name" : "YYY",
"id" : "2",
"Salary" : [
{
"Month" : "YYYY",
"Amount" : "YYYY",
},
{
"Month" : "YYYY",
"Amount" : "YYYY",
},
{
"Month" : "YYYY",
"Amount" : "YYYY",
}
]
}
],
}
This is sample of json format in mongodb document.
I want to get the result as a one particular element from employees Array that search by name
I tried these methods
db.abc.find({"employees.name": "XXX"},{employees: {$elemMatch: {name: "XXX"}}});
and
db.abc.find({ employees: { $elemMatch: { name: "XXX"} } })
none of those won't work. those methods give whole document as a result. can anyone give me a solution on that.

Try this
db.abc.find({"employees.name": "XXX"},{"employees.$":1})

Related

MongoDB query filter array of objects and format return object

I have a MongoDB collection like this:
{
"_id" : "course1",
"teams" : [
{
"key" : "1548600639880X5269760768997986",
"title": "Team One",
"members" : {
"user1" : true
}
},
{
"key" : "1548601941683X14679065888073906",
"title": "Team Two",
"members" : {
"user2" : true,
"user3" : true
}
},
{
"key" : "1548602385020X41594057288000386",
"title": "Team Three",
"members" : {
"user4" : true
}
}
],
"updated_at" : "2019-01-27T15:31:43+00:00"
}
I'am trying to get the "team" of user2 with all user with value true. So the return object schould be something like this:
{
"key" : "1548601941683X14679065888073906",
"title": "Team Two",
"members" : {
"user2" : true,
"user3" : true
}
}
I tried a lot with db.getCollection('').find({}) but did not get the needed result.
You need to use aggregation. And below aggregation help you.
db.getCollection('').find({}) can't be convert output into desire result.
db.getCollection('collection').aggregate([
{ $unwind: "$teams" },
{ $match: {"teams.members.user2": true } },
{ $replaceRoot: { newRoot: "$teams" } }
])
db.getCollection('teams').find({
"_id": "course1",
"teams.members": { "user1": true }
})
gets me
{
"_id" : "course1",
"teams" : [
{
"key" : "1548600639880X5269760768997986",
"title" : "Team One",
"members" : {
"user1" : true
}
},
{
"key" : "1548601941683X14679065888073906",
"title" : "Team Two",
"members" : {
"user2" : true,
"user3" : true
}
},
{
"key" : "1548602385020X41594057288000386",
"title" : "Team Three",
"members" : {
"user4" : true
}
}
],
"updated_at" : "2019-01-27T15:31:43+00:00"
}

Mongodb Aggregate JSON array field for the matching field of other collection

I am new to mongodb , I have two collections like this :
1st collection name is A
{
"_id": "1234",
"versions": [{
"owner_id": ObjectId("100000"),
"versions": 1,
"type" : "info",
"items" : ["item1","item3","item7"]
},
{
"owner_id": ObjectId("100001"),
"versions": 2,
"type" : "bug",
"OS": "Ubuntu",
"Dependencies" : "Trim",
"items" : ["item1","item7"]
}
]}
2nd Collection name is B
{ "_id": ObjectId("100000"), "email": "abc#xyz.com" } { "_id": ObjectId("100001"), "email": "bbc#xyz.com"}
Expected output is :
{
"_id": "1234",
"versions":[{
"owner_id": "abc#xyz.com",
"versions": 1,
"type" : "info",
"items" : ["item1","item3","item7"]
},
{
"owner_id": "bbc#xyz.com",
"versions": 2,
"type" : "bug",
"OS": "Ubuntu",
"Dependencies" : "Trim",
"items" : ["item1","item7"]
}
] }
I used mongo $lookup but I am not getting required output
Please help.
Thank You!!!
You need to $unwind versions, $lookup with another collection on foreignField, $project to take the first element from the match array, $group to get back in original document format
collection a
> db.a.find()
{ "_id" : "1234", "versions" : [ { "owner_id" : "100000" }, { "owner_id" : "100001" }, { "owner_id" : "100001" } ] }
collection b
> db.b.find()
{ "_id" : "100000", "email" : "abc#xyz.com" }
{ "_id" : "100001", "email" : "bbc#xyz.com" }
aggregate pipeline
> db.a.aggregate(
[
{$unwind:"$versions"},
{$lookup : {from : "b", "localField":"versions.owner_id", "foreignField":"_id", as :"out"}},
{$project : {"_id":1, "versions.owner_id":{$arrayElemAt:["$out.email",0]}}},
{$group:{_id:"$_id", versions : {$push : "$versions"}}}
]
).pretty()
output
{
"_id" : "1234",
"versions" : [
{
"owner_id" : "abc#xyz.com"
},
{
"owner_id" : "bbc#xyz.com"
},
{
"owner_id" : "bbc#xyz.com"
}
]
}

Mongodb Aggregate : replace value of one collection with matching value of other collection

I am new to MongoDB, I have two collections like this :
1st collection name is a
db.a.find()
{
"_id": "1234",
"versions": [{
"owner_id": ObjectId("100000"),
"versions": 1,
"type" : "info",
"items" : ["item1","item3","item7"]
},
{
"owner_id": ObjectId("100001"),
"versions": 2,
"type" : "bug",
"OS": "Ubuntu",
"Dependencies" : "Trim",
"items" : ["item1","item7"]
}
]}
2nd Collection name is b
db.b.find()
{
"_id": ObjectId("100000"),
"email": "abc#xyz.com"
} {
"_id": ObjectId("100001"),
"email": "bbc#xyz.com"
}
Expected output is:
{
"_id": "1234",
"versions":[{
"owner_id": "abc#xyz.com",
"versions": 1,
"type" : "info",
"items" : ["item1","item3","item7"]
},
{
"owner_id": "bbc#xyz.com",
"versions": 2,
"type" : "bug",
"OS": "Ubuntu",
"Dependencies" : "Trim",
"items" : ["item1","item7"]
}
] }
Requirement: fields inside each document of versions are not fixed,
Example : versions[0] have 4 key-value pair and versions[1] have 6 key-value pair.
so I am looking a query which can replace owner_id with email keeping all other filed in output.
I tried :
db.a.aggregate(
[
{$unwind:"$versions"},
{$lookup : {from : "b", "localField":"versions.owner_id", "foreignField":"_id", as :"out"}},
{$project : {"_id":1, "versions.owner_id":{$arrayElemAt:["$out.email",0]}}},
{$group:{_id:"$_id", versions : {$push : "$versions"}}}
]
).pretty()
Please help.
Thank You!!!
Instead of $project pipeline stage use $addFields.
Example:
db.a.aggregate([
{ $unwind: "$versions" },
{
$lookup: {
from: "b",
localField: "versions.owner_id",
foreignField: "_id",
as: "out"
}
},
{
$addFields: {
"versions.owner_id": { $arrayElemAt: ["$out.email",0] }
}
},
{ $group: { _id: "$_id", versions: { $push: "$versions" } } }
]).pretty()

Elasticsearch - how to filter/query for a parameter value?

I'm new to Elasticsearch and I have the following question about parameter comparison at filter/query:
In SQL I have something like the code below, where I compare a SQL value with a parameter value and the parameter value with a fixed value
WHERE (customer.id = :customer_id OR :customer_id = '111')
The left part of the OR above is ok, but how I compare the right part?
{ "bool": {
"should": [
{ "term":
{ "customer.id": "#customer_id" }
},
{
????
}
]
}}
Thanks in advance.
UPDATE
The mapping:
{
"_id" : {
"store" : true,
"index" : "not_analyzed"
},
"_timestamp" : {
"enabled" : true,
"store" : true
},
"properties" : {
...
"processDefinition.id" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"processDefinition.key" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"processDefinition.name" : {
"type" : "string"
},
"variables" : {
"type" : "nested",
"properties" : {
...
"executionId" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"id" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"name" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"originalType" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"rawValue" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"storedType" : {
"type" : "string",
"index" : "not_analyzed",
"doc_values" : true
},
"stringValue" : {
"type" : "string"
}
}
}
}
}
I want every "variables.rawValue": "#parameter" OR "#parameter": "ABC". Keep in mind that if #parameter is equals to "a", then the filter returns only info related to "a". If #parameter is equals to "ABC", then the filter returns info related to everything, because company ABC is owner of everything sub company (like "a). I can have a user from "a" using the filter or a user from "ABC".
I tried this:
"bool": {
"should": {
"terms": {
"variables.rawValue": [
"#currentUser_company",
"ABC"
]
}
}
}
But the filter join the result from "a" with "ABC".
One last thing. The ES version is 1.7.
Have you tried this:
{
"query": {
"bool": {
"should": [
{
"terms": {
"FIELD": [
"#customer_id",
"111"
]
}
}
]
}
}
}
#customer_id is the value which user passes

How to unwind single document and then process into single result in an array

I have had some great help from #Joao and #Blakes Seven in order to get me as far as I've got. Awesome, thanks guys very much.
What I have a problem with is going from my original simple example and applying it to my real life scenario.
Where I've got to is two separate scripts which work perfectly by themselves but when I try to being the two together, it then only does the first part without applying the second part; it's my lack of experience in Mongo letting me down here.
So, I am able to get a name value pair from the first array set within a document using the following code:
db.raw_originBusinessData.aggregate([
{ "$match": {objectOriginAPI : "Profit & Loss"}}
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
,{ "$group": {"_id": "$_id","first": { "$first": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
, "temp": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
{ "$unwind": "$temp" }
,{"$skip":1}
,{ "$group": {"_id": "$_id", "AccountBalance":{ "$first": "$first" }
}}
])
This gives me the result below, which I'm happy with except for the fact I am not able to name the two values in the Account Balances array.
Mission 1: I want AccountBalance to be an array and the first position has two values: "AccountName" : "Sales", "AccountValue" : 5428.04.
{
"result" : [
{
"_id" : ObjectId("564d12da1506995581569428"),
"AccountBalance" : [
"Sales",
"5428.64"
]
}
],
"ok" : 1.0000000000000000
}
The second part of the problem is that it is only processing one set of values whereas, the document I am processing on has 9 sets to do. I have run the following $unwind on the document and it has perfectly split them into 9 results:
db.raw_originBusinessData.aggregate([
// find document
{ "$match": {objectOriginAPI : "Profit & Loss"}}
// unwind into multiple documents
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
])
So I get 9 results perfect. Mission 2: What I want to do is to combine this with the script I showed above. I tried the following but it does absolutely no more than the script just above.
db.raw_originBusinessData.aggregate([
// find document
{ "$match": {objectOriginAPI : "Profit & Loss"}}
// unwind into multiple documents
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
]
// process each document
,{ "$unwind": "$objectRawOriginData.Reports" }
, {"$unwind": "$objectRawOriginData.Reports.Rows" }
, {"$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
, {"$group": {"_id": "$_id","first": { "$first": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
, "a": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
{ "$unwind": "$a" }
,{"$skip":1}
,{ "$group": {"_id": "$_id", "AccountBalance":{ "$first": "$first" }
}}
)
Desired Outcome
What I want to get is the following. This is combination of mission 1 and 2.
{
"result" : [
{
"_id" : ObjectId("564d12da1506995581569428"),
"AccountBalance" : [
{"AccountName" : "Sales",
"AccountValue" : "5428.64"},
{"AccountName" : "Total Income",
"AccountValue" : "5428.64"},
{"AccountName" : "Cost of Sales",
"AccountValue" : "100.00"},
{"AccountName" : "Total Cost of Sales",
"AccountValue" : "100.00"},
{"AccountName" : "Gross Profit",
"AccountValue" : "5328.64"},
{"AccountName" : "Advertising",
"AccountValue" : "100.00"},
{"AccountName" : "General Expenses",
"AccountValue" : "100.00"},
{"AccountName" : "Total Operating Expenses",
"AccountValue" : "200.00"},
{"AccountName" : "Net Profit",
"AccountValue" : "5128.64"}
]
}
],
"ok" : 1.0000000000000000
}
The document that I am using as a source is from Xero API - it's one of their reports. It has the same pattern as most reports exported in JSON like Oracle. Below is the actual report so that you have it for reference.
Thanks a million guys, very much appreciated!
{
"_id" : ObjectId("564d12da1506995581569428"),
"objectClass" : "Origin Data",
"objectCategory" : "Application",
"objectType" : "Customer",
"connection_id" : "562033dfca91840cd0c7c54f",
"connectionName" : "Building Accounts",
"entity_id" : "564149bcca9183a8d0c7c83c",
"objectCreationDate" : "2015-11-19 14:43:40",
"objectCycleID" : "12345678",
"objectStatus" : "PROCESSED",
"objectOrigin" : "Xero",
"objectOriginAPI" : "Profit & Loss",
"objectOriginService" : "Xero API - Profit & Loss v 1.0.0.8",
"objectRawOriginData" : {
"Id" : "d6e7fb37-9f2e-45ae-b0a4-de62aa95a783",
"Status" : "OK",
"ProviderName" : "Xero API Previewer",
"DateTimeUTC" : "/Date(1443405874333)/",
"Reports" : [
{
"ReportID" : "ProfitAndLoss",
"ReportName" : "Profit and Loss",
"ReportType" : "ProfitAndLoss",
"ReportTitles" : [
"Profit & Loss",
"Paddy's markets",
"28 September 2014 to 28 September 2015"
],
"ReportDate" : "28 September 2015",
"UpdatedDateUTC" : "/Date(1443405874333)/",
"Fields" : [],
"Rows" : [
{
"RowType" : "Header",
"Cells" : [
{
"Value" : ""
},
{
"Value" : "28 Sep 15"
}
]
},
{
"RowType" : "Section",
"Title" : "Income",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Sales",
"Attributes" : [
{
"Value" : "a7e3f9e4-6f63-4b25-ae36-107131e8b9be",
"Id" : "account"
}
]
},
{
"Value" : "5428.64",
"Attributes" : [
{
"Value" : "a7e3f9e4-6f63-4b25-ae36-107131e8b9be",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "SummaryRow",
"Cells" : [
{
"Value" : "Total Income"
},
{
"Value" : "5428.64"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "Less Cost of Sales",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Cost of Sales",
"Attributes" : [
{
"Value" : "f78f7118-ad98-4862-a63c-39dd3c5ace8a",
"Id" : "account"
}
]
},
{
"Value" : "100.00",
"Attributes" : [
{
"Value" : "f78f7118-ad98-4862-a63c-39dd3c5ace8a",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "SummaryRow",
"Cells" : [
{
"Value" : "Total Cost of Sales"
},
{
"Value" : "100.00"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Gross Profit"
},
{
"Value" : "5328.64"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "Less Operating Expenses",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Advertising",
"Attributes" : [
{
"Value" : "67466588-132b-48ce-b897-0ceabffd7a9d",
"Id" : "account"
}
]
},
{
"Value" : "100.00",
"Attributes" : [
{
"Value" : "67466588-132b-48ce-b897-0ceabffd7a9d",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "General Expenses",
"Attributes" : [
{
"Value" : "fdb25d7a-2fc8-406a-bf4b-6b4e8014b8cb",
"Id" : "account"
}
]
},
{
"Value" : "100.00",
"Attributes" : [
{
"Value" : "fdb25d7a-2fc8-406a-bf4b-6b4e8014b8cb",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "SummaryRow",
"Cells" : [
{
"Value" : "Total Operating Expenses"
},
{
"Value" : "200.00"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Net Profit"
},
{
"Value" : "5128.64"
}
]
}
]
}
]
}
]
}
}
done it, see below, thanks:
db.raw_originBusinessData.aggregate([
{ "$match": {objectOriginAPI : "Profit & Loss"}}
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
,{ "$group": {"_id": "$_id","accountBalances": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
])