firebase query by array of child - angularjs

I have this document structure
{
"parking" : {
"-Kace9LLJBuhG1RBWsy2" : {
"address" : "avenida",
"company_name" : "Company",
"hours" : 40,
"owner" : "Fmex7wiYAsbxNFhDy39X1r28J9L2",
"receipts" : [
{
"id" : "-KbB-0Wxxx_vsCxy",
"date" : "3/01/2017",
"user_id" : "Fmex7wiYAsbxNFhDy39X1r28J9L2",
"value" : 50
},
{
"id" : "-KbB-0Wzzzz_vsCy",
"date" : "3/30/2017",
"user_id" : "Fmex7wiYAsbxNFhDy39X1r28J9L2",
"value" : 50
}
],
"social_name" : "Company",
"value" : "50"
},
Is it possible for me to pick up a parking lot, using the id of a receipt?
Example: I want to show the user a parking only if the user ID is inside the receipts array
Or do not you want to do this with the firebase and I would have to create a reference instead of a subdocument?
EDIT
I've tried something like:
var refParkingByUser = firebase.database().ref('parking').orderByChild('receipts').equalTo(Auth.$getAuth().uid);
But how do I access the receipt elements?

As Frank mentioned you can't do that with your data. If you add in another node that looks like this:
{
"recieptParkingLots": {
"-KbB-0Wxxx_vsCxy": {
"-Kace9LLJBuhG1RBWsy2": true
},
"-KbB-0Wzzzz_vsCy": {
"-Kace9LLJBuhG1RBWsy2": true
}
}
}
You'd easily be able to find which parking lots a receipt is attached too.
If you can only have one receipt per parking lot I'd store them outside the parking lot node:
{
"parking" : {
"-Kace9LLJBuhG1RBWsy2" : {
"address" : "avenida",
"company_name" : "Company",
"hours" : 40,
"owner" : "Fmex7wiYAsbxNFhDy39X1r28J9L2",
"receipts" : {
"-KbB-0Wxxx_vsCxy" : true,
"-KbB-0Wzzzz_vsCy" : true
}
"social_name" : "Company",
"value" : "50"
},
}
"receipts" : {
"-KbB-0Wxxx_vsCxy" : {
"parking" : "-Kace9LLJBuhG1RBWsy2",
"date" : "3/01/2017",
"user_id" : "Fmex7wiYAsbxNFhDy39X1r28J9L2",
"value" : 50
},
"-KbB-0Wzzzz_vsCy" : {
"parking" : "-Kace9LLJBuhG1RBWsy2",
"date" : "3/30/2017",
"user_id" : "Fmex7wiYAsbxNFhDy39X1r28J9L2",
"value" : 50
}
}
}
Then you can easily look up the parking lot and then go and get the receipt.

Related

Remove objects within array in MongoDB

I need to remove all the objects within array who meet the conditions i will show down below. I'll let here the documents and an example of what i've done.
//document 1
{
"_id" : ObjectId("5ec73abebd7e4d618a057350"),
"code" : "X20",
"title" : "Full stack developer",
"location" : "Paris",
"date" : ISODate("2020-05-22T02:36:46.272Z"),
"candidates" : [
{
"name" : "David",
"last_name" : "Broncano",
"telephone" : "642025552",
"email" : "david#gmail.com"
},
{
"name" : "Pablo",
"last_name" : "Claros",
"telephone" : "628721784",
"email" : "pablo#gmail.com"
}
]
}
// document 2
{
"_id" : ObjectId("4ec73abebd7e4d618a057350"),
"code" : "X50",
"title" : "Full stack developer",
"location" : "Madrid",
"date" : ISODate("2020-05-22T02:36:46.272Z"),
"candidates" : [
{
"name" : "Maria",
"last_name" : "Mars",
"telephone" : "642024582",
"email" : "dasd#gmail.com"
},
{
"name" : "Pablo",
"last_name" : "Claros",
"telephone" : "628721784",
"email" : "pablo#gmail.com"
}
]
}
So i need to remove all the candidates where location is Madrid.I have done this but it removes the field. Is it possible to just remove the content of it using $pull or something?
db.offers.update(
{ location : "Madrid"},
{
$unset:{
"candidates":""
} } ,
{
multi : true
}
)
According to my understanding, you need to just clear the candidates array and maintain that as candidates: []. For this, you can use use $set operator to set candidates to [] based on your condition
db.offers.update({ location : "Madrid"}, { $set:{ "candidates": [] } } , { multi : true })

Problems with JSON

I'm trying to Order in ascending order the requirements that are not between 25,000 and 30,000. The requirements are information of an array which is inside of a document and the condition is that they can't be in that determined range. I'm trying to do it properly but i can't find any information about this.
Document structure
{
"_id" : ObjectId("5ec73abebd7e4d618a05734e"),
"code" : "A47",
"title" : "Software engineer",
"description" : "Analyze, design, create, test computer and software systems.",
"city" : "Madrid",
"date" : ISODate("2020-05-22T02:36:46.271Z"),
"salary" : 30000.0,
"active" : true,
"requirements" : [
"python",
"java",
"html5",
"C++",
"C#"
],
"info_company" : {
"cif" : "A00000000",
"name" : "FUTURE S.A",
"location" : "Madrid",
"web" : "www.future.es",
"about" : "We are a leading company in new technologies."
},
"pyme" : true
}
db.offers.update(
{ $ne : [ salary: {
$gte : 25000,
$lte : 35000 ]
} },
{
$push : {
requirements: {
$each : [] ,
$sort : 1
}
}
}
,
{
multi : true
} )

Mongo matching only where first element of array has certain field value

I have a query below that extracts a couple of values from a large nested document. It tells me the user id and the first item name for each order.
This works fine, however I want it to only return the record where the first item's name is not null and is not blank. I can't figure out how to add a second query to the $match operator below to achieve this
db.getCollection('Orders').aggregate
([
{ $match : { "Items.1" : { $exists : true }}, ???},
{ $project: {
_id:0,
'UserId': '$User.EntityId',
'ItemName': {$arrayElemAt: ['$Items.Details.ItemName', 0]}
}
}
]);
Edited to show sample document
{
"_id" : "order-666156",
"State" : "ValidationFailed",
"LastUpdated" : {
"DateTime" : ISODate("2017-09-26T08:54:16.241Z"),
"Ticks" : NumberLong(636420128562417375)
},
"SourceOrderId" : "666156",
"User" : {
"EntityId" : NumberLong(34450),
"Name" : "Bill Baker",
"Country" : "United States",
"Region" : "North America",
"CountryISOCode" : "US",
},
"Region" : null,
"Currency" : null,
"Items" : [
{
"ClientOrderId" : "18740113",
"OrigClientOrderId" : "18740113",
"Quantity" : NumberDecimal("7487.0"),
"TransactDateTime" : {
"DateTime" : Date(-62135596800000),
"Ticks" : NumberLong(0)
},
"Text" : null,
"LocateRequired" : false,
"Details" : {
"ItemName" : "Test Item 1",
"ItemCost" : 1495.20
}
},
{
"ClientOrderId" : "18740116",
"OrigClientOrderId" : "18740116",
"Quantity" : NumberDecimal("241.0"),
"TransactDateTime" : {
"DateTime" : Date(-62135596800000),
"Ticks" : NumberLong(0)
},
"Text" : null,
"LocateRequired" : false,
"Details" : {
"ItemName" : "Test Item 2",
"ItemCost" : 2152.64
}
}
]
}
You need to add the two conditions to your existing $match (not null and not blank) to check the Items as:
$match : { "Items.1" : { $exists : true, "$ne": null,"$ne":""}
If you want to check the element Items[0].Details.ItemName you can doing using the operator $and
{ $match : {
$and: [
{"Items.1" : { $exists : true }},
{"Items.Details.ItemName" : { $ne : null}},
{"Items.Details.ItemName" : { $ne : ""}},
]
}},

Why I can't get the full document form array?

I have this document in stored in my collection:
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"companyId" : ObjectId("570269639caabe24e4e4043e"),
"descriptions" : [
{ "id" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test" },
{ "id" : ObjectId("570cd8164fff3a20f88c0dc9"), "description" : "test1" },
{ "id" : ObjectId("570ce6ba4fff3a052c8c570f"), "description" : "etr" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71716"), "description" : "43" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71717"), "description" : "43" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71719"), "description" : "345" }
],
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test" },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test1" }
]
}
Now I'm trying to get the objects from the options array that are matching the descriptionId and here is how I'm doing it
db.CustomFields.find({companyId: ObjectId("570269639caabe24e4e4043e")},{"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")})
But the result contains only the descriptionId - the description property is missing.
here is how the result looks like:
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a") },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a") }
]
}
Why my query is not returning the full document from the array, but only a part of it? Can you give me a push?
EDIT
This is what I'm expecting to get from the query
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a", "description" : "test") },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a", "description" : "test1") }
]
}
You need to include the other query with "options.descriptionId" together with the companyId query and use projection to return just the array you want.
The following shows this:
db.customFields.find(
{
"companyId": ObjectId("570269639caabe24e4e4043e"),
"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")
},
{ "options": 1 }
);
Output
{
"_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{
"descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"),
"description" : "test"
},
{
"descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"),
"description" : "test1"
}
]
}
Try this
db.CustomFields.find({companyId: ObjectId("570269639caabe24e4e4043e"),"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")})

How to get just element that matches query in a mongo find operation? [duplicate]

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 8 years ago.
i've got some documents like this:
{
"name" : "xxx",
"address" : " ",
"mail" : "",
"url" : "",
"pos" : {
"lat" : yyy,
"lng" : zzz
},
"rooms" : [
{
"_id" : ObjectId("540ce3f8e4b016292085b387"),
"supplier" : "s1",
"price" : 41000,
"details" : [
{
"price" : 25200,
"key" : "2-1"
},
{
"price" : 15800,
"key" : "2-0"
}
]
},
{
"_id" : ObjectId("540ce3f8e4b016292085b3fd"),
"supplier" : "s2",
"price" : 44900,
"details" : [
{
"price" : 27000,
"key" : "2-1"
},
{
"price" : 17900,
"key" : "2-0"
}
]
},
{
"_id" : ObjectId("540ce3f8e4b016292085b53d"),
"supplier" : "s3",
"price" : 53500,
"details" : [
{
"price" : 32100,
"key" : "2-1"
},
{
"price" : 21400,
"keykey" : "2-0"
}
]
}
]
}
What i need to do is execute a find with some filters AND price range query to fetch just the matching array elements and not all:
This is what i try:
var sort = {};
var query = {name:new RegExp("xx",'i')};
query['$and'] = [{'rooms.price':{$gt:50000}},{'rooms.price':{$lt:100000}}];
var page = 1;
var ppp = 20;
db.collection("myCollection").
find(query).
sort(sort).
skip(page > 0 ? ((page-1)*ppp) : 0).limit(ppp).toArray(function(err, docs) {
res.send(docs);
});
and i retrieve the same document.
What i need is :
{
"name" : "xxx",
"address" : " ",
"mail" : "",
"url" : "",
"pos" : {
"lat" : yyy,
"lng" : zzz
},
"rooms" : [
{
"_id" : ObjectId("540ce3f8e4b016292085b53d"),
"supplier" : "s3",
"price" : 53500,
"details" : [
{
"price" : 32100,
"key" : "2-1"
},
{
"price" : 21400,
"keykey" : "2-0"
}
]
}
]
}
I googled about but i find just aggregate or map/reduce element.
I'd like to avoid it.
Is there a good solution??
Thanks!
If you don't want to use aggregate or map/reduce then you could change your data structure.
Extract rooms to it's own collection and make sure that every element has id reference to the appropriate document from myCollection. This would require at least two query though.
Alternatively, you could filter the content on the application side and not within mongodb.

Resources