I've this entry:
"entries": {
"members": {
"person": [
{
"name": "Jane Doe",
}
]}}
Now I would like to check if the persons array is empty or has some entries.
I already tried with $exists:
"selector": {
"entries": {
"members": {
"person": {
"name": {
"$exists": true
}
}
}
}
}
}
And with $neq
"selector": {
"entries": {
"members": {
"person": {
"name": {
"$neq": ""
}
}
}
}
}
}
Both approaches don't work..any tips?
you may want try using the $size operator. for example,
"selector": {
"entries": {
"members": {
"person": {
"$size": 0
}
}
}
}
I did it with:
"entries.members.person": {
"$elemMatch": {
"name": {
"$exists": true
}
}
}
Related
{
"_id": "null",
"data": [
{
"name": "abc",
"id": "123"
},
{
"name": "xzy",
"id": "123"
}
]
}
Explanation: the name value will become an object name. also want to convert it into one single document, that contains all the objects. abc and xyz is dynamically coming as a parameter.
Expected Output.
{
"data": {
"abc": {
"name": "abc",
"id": "100"
},
"xyz": {
"name": "xzy",
"id": "123"
}
}
}
Try this:
db.testCollection.aggregate([
{
$project: {
"array": {
$map: {
input: "$data",
as: "item",
in: {
k: "$$item.name",
v: {
"name": "$$item.id",
"id": "$$item.name"
}
}
}
}
}
},
{ $unwind: "$array" },
{
$group: {
_id: "$null",
"data": { $push: "$array" }
}
},
{
$project: {
"data": { $arrayToObject: "$data" }
}
}
]);
Here i was trying merge elements from 2 child arrays in to its parent one and leave the other one and move the second array to two levels up.
Is there a way to change value on condition, like in the input below,
parties.party.sno ="1" , can this updated as parties..sno='Y'
input:
{
"Parties": [
{
"party": {
"partyId": "100005767",
"sno": 1,
"fn": "Th1mas",
"ln": "Edison",
"emails": [
{
"emailAddress": "jkjk#ui.com"
}
],
"addresses": [
{
"zip": ""
}
],
"shealth": [
{
"stcd": "TN",
"lno": "1"
}
]
},
"seq": {
"typeCd": "1"
}
}
]
}
Expected output:
{
"person": {
"first_name": "Th1mas",
"middle_initial": "Edison",
"last_name": "",
"email_address": "jkjk#ui.com",
"pinCode": ""
},
"shealth": {
"statecd": "ON"
},
//this is the seq no from party.sno
"primary": "Y",
"typeCd": "1"
}
tried spec like this:
[
{
"operation": "shift",
"spec": {
"Parties": {
"*": {
"party": {
"emails": {
"*": {
"emailAddress": "[&1].email_address",
"#(2,fn)": "[&1].first_name",
"#(2,ln)": "[&1].last_name"
}
},
"addresses": {
"*": {
"zip": "[&1].pinCode"
}
},
"shealth": {
"*": {
"stcd": "[&1].statecd"
}
}
}
}
}
}
}
]
This spec works,
"party": {
"sno": {
"1": {
"#Y": "primary"
}
},
Try applying the condition from the current level,
[
{
"operation": "shift",
"spec": {
"Parties": {
"*": {
"party": {
"sno": {
"1": {
"#Y": "primary"
}
},
"emails": {
"*": {
"emailAddress": "person.email_address",
"#(2,fn)": "person.first_name",
"#(2,ln)": "person.last_name"
}
},
"addresses": {
"*": {
"zip": "person.pinCode"
}
},
"shealth": {
"*": {
"stcd": "shealth.statecd"
}
}
},
"seq": {
"typeCd": "typeCd"
}
}
}
}
}
]
I have documents like these:
Doc1
{
"id": ...,
...
"articles": [
{
"id": "5cdd17c7e24f6e05d487b2c2#142936",
...
},
{
"id": "5cdd17c7e24f6e05d487b2c2#226536",
...
}
...
}
Doc2
{
"id": ...,
...
"articles": [
{
"id": "5cdd17c7e24f6e05d487b2c2#142936",
...
},
{
"id": "5cdd17c7e24f6e05d487b2c2#226536",
...
},
{
"id": "5cdd17c7e24f6e05d487b2c2#142965",
...
}
...
}
Doc3
{
"id": ...,
...
"articles": [
{
"id": "5cdd17c7e24f6e05d487b2c2#142936",
...
}
...
}
And I want the document exactly has the array of articles I need. For example, if my Array of article Ids is ['5cdd17c7e24f6e05d487b2c2#142936', '5cdd17c7e24f6e05d487b2c2#226536'] I only want to get the Doc1.
Now I have this query:
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "articles",
"query": {
"query_string": {
"default_field": "articles.id",
"query": "5cdd17c7e24f6e05d487b2c2#142936 AND 5cdd17c7e24f6e05d487b2c2#226536"
}
}
}
}
]
}
}
}
But with this, I get Doc1 & Doc2...
Assuming articles.id is of type keyword, I think this should work for you (not sure it's the most efficient way to write the query):
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "articles",
"query": {
"term": {
"articles.id": "5cdd17c7e24f6e05d487b2c2#142936"
}
}
}
},
{
"nested": {
"path": "articles",
"query": {
"term": {
"articles.id": "5cdd17c7e24f6e05d487b2c2#226536"
}
}
}
}
],
"must_not": {
"nested": {
"path": "articles",
"query": {
"query_string": {
"default_field": "articles.id",
"query": "NOT 5cdd17c7e24f6e05d487b2c2#142936 AND NOT 5cdd17c7e24f6e05d487b2c2#226536"
}
}
}
}
}
}
}
I have about MongoDB in unwind operator.
So, I have document like this.
{
"name": "abc",
"report": {
"_2019": {
"May": {
"_9": {
"DATA": [{
"image": "xyz.png",
"object": true
},
{
"image": "abc.png",
"object": true
}
]
},
"_10": {
"DATA": [{
"image": "ejf.png",
"object": false
},
{
"image": "qwe.png",
"object": false
}
]
}
},
"June": {
"_1": {
"DATA": [{
"image": "jsk.png",
"object": false
}]
}
}
},
"_2020": {
"January": {
"_30": {
"DATA": [{
"image": "hhg.png",
"object": false
}]
}
}
}
}
}
And want to format the output for something like this
[{
"image": "xyz.png",
"object": true
}, {
"image": "abc.png",
"object": true
}, {
"image": "ejf.png",
"object": false
}, {
"image": "qwe.png",
"object": false
}, {
"image": "jsk.png",
"object": false
}, {
"image": "hhg.png",
"object": false
}]
The first thing i found is that using unwind, but it only accept array. And the second is using foreach in the programming-side. But i think it's not effective. Is this possible? Thank you.
The problem here is that the keys like _2020 or January or _30 are dynamically generated. To access subdocuments from DATA level you need to get there by using $objectToArray and $map to take values from key-value pairs. After each of these steps you need $unwind and then in the last step you can run $replaceRoot to promote documents from DATA into root level:
db.col.aggregate([
{
$project: {
data: {
$map: {
input: { $objectToArray: "$report" },
in: "$$this.v"
}
}
}
},
{ $unwind: "$data" },
{
$project: {
data: {
$map: {
input: { $objectToArray: "$data" },
in: "$$this.v"
}
}
}
},
{ $unwind: "$data" },
{
$project: {
data: {
$map: {
input: { $objectToArray: "$data" },
in: "$$this.v"
}
}
}
},
{ $unwind: "$data" },
{ $unwind: "$data.DATA" },
{
$replaceRoot: {
newRoot: "$data.DATA"
}
}
])
Mongo Playground
Let's say I have many records in my database similar to this one
{
"basename": "2020bb",
"entries": [
{
"name": "030-c1.bin",
"extension": "bin",
"basename": "030-c1",
"crc": "4f5e19bd",
"size": 1048576
},
{
"name": "030-c2.bin",
"extension": "bin",
"basename": "030-c2",
"crc": "d6314bf0",
"size": 1048576
},
{
"name": "030-c3.bin",
"extension": "bin",
"basename": "030-c3",
"crc": "47fddfee",
"size": 1048576
}
]
}
they all have that structure, but different basenames different entries
Now I have a list of basenames and crcs of entries that I want to find records for. Like so:
{
"basename": {
"$in": [
"2020bb",
"alpham2p"
]
},
"entries": {
"$in": [
[
{ "$elemMatch": { "crc": "4f5e19bd" } },
{ "$elemMatch": { "crc": "d6314bf0" } },
{ "$elemMatch": { "crc": "47fddfee" } }
],
[
{ "$elemMatch": { "crc": "c763e52a" } },
{ "$elemMatch": { "crc": "7a0b435c" } },
{ "$elemMatch": { "crc": "efc9ae2e" } }
]
]
}
}
With this query I am trying to find the items that have
the basename 2020bb and entries with the crc values 4f5e19bd, d6314bf0, 47fddfee
the basename alpham2p and the entries with the crc values c763e52a, 7a0b435c, efc9ae2e
I hope my intention is clear. Sadly this just gives me 0 results.
db.collection.find({
basename: {
"$in": ["2020bb", "alpham2p"]
},
entries: {
$elemMatch: {
crc: {
$in: ["4f5e19bd", "d6314bf0", "47fddfee", "c763e52a", "7a0b435c", "efc9ae2e"]
}
}
}
})