Remove Subdocument items with $pull - express

I'm trying to remove items from subdocuments using ExpressJS and Mongoose but it is only removing the first items, not the sub items.
So I want to remove "subitem 2" in the messages Array
This is the structure:
{
"_id" : ObjectId("5c4ee94b30ebd71cbed89a35"),
"title" : "Test",
"subitem" : [
{
"_id" : ObjectId("5c4ee95630ebd71cbed89a36"),
"title" : "Item 1",
"messages" : [
{
"_id" : ObjectId("5c4ee95f30ebd71cbed89a37"),
"type" : "single_article",
"date" : "Jan 28, 2019",
"title" : "subitem 1",
"text" : ""
}
]
},
{
"_id" : ObjectId("5c4ee96830ebd71cbed89a38"),
"title" : "item 2",
"messages" : [
{
"_id" : ObjectId("5c4ee96e30ebd71cbed89a39"),
"type" : "single_article",
"date" : "Jan 28, 2019",
"title" : "subitem 2",
"text" : ""
}
]
}
],
"__v" : 0
}
And this is the $pull method:
getController.deleteRec = function(req,res,collection){
var id = req.params.id;
console.log(id);
collection.updateOne({'subitem.messages._id': id}, {$pull: {'subitem.0.messages': {"_id": id}}}).
then(function(result){
console.log(result);
});
};
Now I know why it is only deleting the first item because I have "subitem.0.messages". How can I loop over this, so it can delete all items?

You can use $ as a wildcard index, removing all elements in the array matching your query like this:
{$pull: {'subitem.$.messages': {"_id": id}}}
if you want to remove multiple documents:
{$pull: {'subitem.$.messages': {"_id": {$in : [id, id2, id3...]}}}}

Related

How could I create indexes in postgres using jsonb?

I have a table in my database as follows
my_table:jsonb
[ {
"name" : "world map",
"type" : "activated",
"map" : [ {
"displayOrder" : 0,
"value" : 123
}, {
"displayOrder" : 1,
"value" : 456
}, {
"displayOrder" : 2,
"value" : 789
} ]
}, {
"name" : "regional map",
"type" : "disabled"
} ]
I would like to create indices for the name, type and displayOrder fields, which would be the best way?

i want to query the double nested dates in mongodb

----------Query i have tried----------
db.getCollection('rates').aggregate([
{ $match: { "userId" : "5d4c4f69341b7b1746c80d13"}},
{ $unwind: '$ratewithdate.daywiserates'},{$match : {"$and" :
[{"ratewithdate.daywiserates.date" :{$gte :new ISODate("2019-09-
23T00:00:00.000Z")} },
{"ratewithdate.daywiserates.date" :{$lte :new ISODate("2019-09-
27T00:00:00.000Z")}}]}}])
-------------------------------------------------------------
In My query is here i want to know the query between two dates ,i want
get the data between two dates in the array? am unable to do that ,can
any one send me query,
here my question is i want get the date range from given date to next 30
days,i have tried with aggregate but data become slow..can any one suggest
any better solution for the making query formation
i have tried with aggregation as well find queries am not able find any
results,my goal here is find get the data between two dates,for example
if i selected 2019-09-23T10:43:14.239Z thi date from this date i wanna i
want to show the data.
please send me your value able suggestions to, am not bale to query with
double nested array queries in mongodb,please send me your value able
suggestions to,am not bale to query with double nested array queries in
mongodb please send me your value able suggestions to,
am not bale to query with double nested array queries in mongodb.
please send me your value able suggestions to, am not bale to query with
double nested array queries in mongodb,please send me your value able
suggestions to,am not bale to query with double nested array queries in
mongodb please send me your value able suggestions to,
am not bale to query with double nested array queries in mongodb
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1bff"),
"alloted_roomid" : [],
"name" : "working_rate3",
"description" : "bitcpin",
"type" : "room",
"value" : null,
"inclusive" : "General",
"refundable" : {
"cancellationWindow" : "",
"outsideWindowPenalty" : "",
"insideWindowPenalty" : ""
},
"nonRefundable" : true,
"cancellationWindow" : "",
"daysWiseRate" : "30",
"insideWindowPenalty" : "",
"outsideWindowPenalty" : "",
"deviations" : 980,
"policy" : "",
"funds" : "nonRefundable",
"vat" : 890,
"other_tax" : 90,
"roomRates" : [
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c00"),
"roomId" : ObjectId("5d7c8f2950a6c766c64b2a46"),
"roomName" : "Basic",
"rate" : 9888
}
],
"userId" : "5d4c4f69341b7b1746c80d13",
"hotelCode" : 10034,
"ratewithdate" : [
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c01"),
"roomCategory" : "Basic",
"roomId" : ObjectId("5d7c8f2950a6c766c64b2a46"),
"createdAt" : ISODate("2019-09-21T10:43:14.243Z"),
"daywiserates" : [
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c1f"),
"date" : ISODate("2019-09-21T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c1e"),
"date" : ISODate("2019-09-22T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c1d"),
"date" : ISODate("2019-09-23T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c1c"),
"date" : ISODate("2019-09-24T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c1b"),
"date" : ISODate("2019-09-25T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c1a"),
"date" : ISODate("2019-09-26T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c19"),
"date" : ISODate("2019-09-27T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c18"),
"date" : ISODate("2019-09-28T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c17"),
"date" : ISODate("2019-09-29T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c16"),
"date" : ISODate("2019-09-30T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c15"),
"date" : ISODate("2019-10-01T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c14"),
"date" : ISODate("2019-10-02T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c13"),
"date" : ISODate("2019-10-03T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c12"),
"date" : ISODate("2019-10-04T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c11"),
"date" : ISODate("2019-10-05T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c10"),
"date" : ISODate("2019-10-06T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c0f"),
"date" : ISODate("2019-10-07T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c0e"),
"date" : ISODate("2019-10-08T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c0d"),
"date" : ISODate("2019-10-09T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c0c"),
"date" : ISODate("2019-10-10T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c0b"),
"date" : ISODate("2019-10-11T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c0a"),
"date" : ISODate("2019-10-12T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c09"),
"date" : ISODate("2019-10-13T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c08"),
"date" : ISODate("2019-10-14T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c07"),
"date" : ISODate("2019-10-15T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c06"),
"date" : ISODate("2019-10-16T10:43:14.239Z"),
"rate" : 9888
},
{
"_id" : ObjectId("5d85fec2e8652a5c20ae1c05"),
"date" : ISODate("2019-10-17T10:43:14.239Z"),
"rate" : 9888
},
]
}
],
"id" : "rat-W262IxTjk",
"__v" : 0
}
Try this:
db.getCollection('rates').aggregate([
{ $match: { "userId" : "5d4c4f69341b7b1746c80d13"}},
{ $unwind: '$ratewithdate'},
{ $unwind: '$ratewithdate.daywiserates'},
{ $match : {
"$and" :[
{ "ratewithdate.daywiserates.date" :{$gte :new ISODate("2019-09-23T00:00:00.000Z")} },
{ "ratewithdate.daywiserates.date" :{$lte :new ISODate("2019-09-27T00:00:00.000Z")} }
]
}
},
{ $addFields: {result: "$ratewithdate.daywiserates"}},
{ $project: {result: 1, _id: 0}}
])

db.find vs db.aggregation to select nested array Object

I'v tried to perform the following query :
db.getCollection('fxh').find({"username": "user1", "pf.acc.accnbr" : 915177},{userid: true, "pf.pfid": true, "pf.acc.accid":true})
and my collection is the following :
{
"_id" : ObjectId("5932fd8f381d4c0a7de21942"),
"userid" : 1496513894,
"username" : "user1",
"email" : "user1#gmail.com",
"fullname" : "User 1",
"pf" : {
"acc" : [
{
"cyc" : [
{
"det" : {
"status" : "New",
"dcycid" : 1496513941
},
"status" : "New",
"name" : "QPT202017_M1",
"cycid" : 1496513940
}
],
"status" : "New",
"accnbr" : 915177,
"accid" : 1496513939
},
{
"cyc" : [
{
"det" : {
"status" : "New",
"dcycid" : 1496552643
},
"status" : "New",
"name" : "QPT202017_S8",
"cycid" : 1496552642
}
],
"status" : "New",
"accnbr" : 73497,
"accid" : 1496552641
}
],
"pfid" : 1496513935,
},
"lastupdate" : ISODate("2017-06-03T18:18:55.080Z"),
"__v" : 0
}
When I execute the query the result is the following :
{
"_id" : ObjectId("5932fd8f381d4c0a7de21942"),
"userid" : 1496513894,
"portfolio" : {
"acc" : [
{
"accid" : 1496513939
},
{
"accid" : 1496552641
}
],
"pfid" : 1496513935
}
}
And my problem is that I need to see only the concerned accid and the result returns the all accid !.
Any idea how just to return the selected accid of accnbr ?
NB : I have also tried to add $ sign at the end of my query , it
selects the right acc but it returns the all objects or I need just
only ONE returned object.
On 6/5/17
I also used the aggregate command instead of find and it get result by using this :
db.getCollection('fxh').aggregate([ { $unwind : "$pf.acc"} , { $match : {"username":"adh1", "pf.acc.accbr": 915177 } }, {$project : {_id:0, accid: "$pf.acc.accid"}}])
But could NOT get a lower level result, when I ran this :
db.getCollection('fxh').aggregate([ { $unwind : "$pf.acc.cyc"} , { $match : {"username":"adh1", "pf.acc.accbr": 915177, "pf.acc.cyc.name": "QPT202017_M1" } }, {$project : {_id:0, cycid: "$pf.acc.cyc.cycid"}}])
Any idea ?
You can try the below aggregation pipeline.
The idea is to $unwind one nested level at a time, starting from the outermost to the innermost.
For each nested level unwinding, you can apply the$match to limit the documents and continue till you have the desired shape.
You can $group it together at the end to get back to the original shape.
db.getCollection('fxh').aggregate([
{ $match : {"username":"adh1"} },
{ $unwind : "$pf.acc"} ,
{ $match : {"pf.acc.accbr": 915177 } },
{ $unwind : "$pf.acc.cyc"},
{ $match : {"pf.acc.cyc.name": "QPT202017_M1" } },
{$project : {_id:0, accid: "$pf.acc.accid", cycid: "$pf.acc.cyc.cycid"}}])

Failure to match strings(Arabic) in CHAI assertion library

I have two arrays:
var array_one = [
{
"accountNo": "1",
"id" : 12,
"name" : "אוצר החייל - 14"
},
{
"accountNo": "1",
"id" : 13,
"name" : "china bank"
}
],
array_two = [
{
"accountNo": "1",
"id" : 12,
"name" : "אוצר החייל - 14"
},
{
"accountNo": "1",
"id" : 13,
"name" : "china bank"
}
];
Both the array's contents are same, but it fails to assert that the two array's have the same content. ie
array_one.should.be.deep.equal(array_two) returns false;
And the reason for failure being the matching of strings in Hebrew.
Cannot figure out a way to match Hebrew strings using CHAI assertion library.

Scoring documents in Lucene 6.2.0

My query in lucene 6.2.0 goes like:
query query = new PhraseQuery.Builder()
.add(new Term("country","russia"))
.setSlop(1)
.build();
Basically among all my documents which are:
{
"_id" : ObjectId("586b723b4b9a835db416fa26"),
"name" : "test",
"countries" : {
"country" : [
{
"name" : "russia"
},
{
"name" : "USA china"
}
]
}
}
{
"_id" : ObjectId("586b73f24b9a835fefb10ca5"),
"name" : "nitika jain",
"countries" : {
"country" : [
{
"name" : "russia and denmrk"
},
{
"name" : "USA china"
}
]
}
}
{
"_id" : ObjectId("586b744f4b9a835fefb10ca7"),
"name" : "arjun",
"countries" : {
"country" : [
{
"name" : "russia pakistan"
},
{
"name" : "india iraq"
}
]
}
}
I want a document which has only russia. Ideally it should be the one highest scored, but instead I get something like "Found 3 hits."
Document<stored,indexed,tokenized<id:586b723b4b9a835db416fa26> stored,indexed,tokenized,omitNorms,indexOptions=DOCS<name:test> stored,indexed,tokenized,omitNorms,indexOptions=DOCS<countries:{ "country" : [ { "name" : "russia"} , { "name" : "USA china"}]}> stored,indexed,tokenized<country:russia> stored,indexed,tokenized<country:USA china>>**0.12874341**
Document<stored,indexed,tokenized<id:586b73f24b9a835fefb10ca5> stored,indexed,tokenized,omitNorms,indexOptions=DOCS<name:nitika jain> stored,indexed,tokenized,omitNorms,indexOptions=DOCS<countries:{ "country" : [ { "name" : "russia and denmrk"} , { "name" : "USA china"}]}> stored,indexed,tokenized<country:russia and denmrk> stored,indexed,tokenized<country:USA china>>**0.12874341**
Document<stored,indexed,tokenized<id:586b744f4b9a835fefb10ca7> stored,indexed,tokenized,omitNorms,indexOptions=DOCS<name:arjun> stored,indexed,tokenized,omitNorms,indexOptions=DOCS<countries:{ "country" : [ { "name" : "russia pakistan"} , { "name" : "india iraq"}]}> stored,indexed,tokenized<country:russia pakistan> stored,indexed,tokenized<country:india iraq>>**0.12874341**
All 3 results are equally scored. How can I get the document with only russia to be highest scored?
In Phrase queries, the slop is zero by default, requiring exact matches. that means that if you modify your query in this way:
query query = new PhraseQuery.Builder()
.add(new Term("country","russia"))
.build();
you'll get what you're looking for.