How to set timestamps in nested arrays - nestjs

Versions
System: windows 10
NodeJS: v12.16.2
Typescript: v 4.1.3
Compiler / Transpiler: tsc
Typegoose(GIT): commithash
mongoose: 5.10.18
nestjs / nestjs-typegoose: 7.5.1 / 7.1.38
My question is how to set timestamps in nested arrays;
Example code here
I tried the code:
#ModelOptions({ schemaOptions: { timestamps: true } })
class childModel {
#prop()
param:String
}
class parentModel {
#prop({ type: childModel})
child:childModel[]
}
When I saved this model: parentModel.create( [{ param: 'xxx' }] ) , then the result is:
{
child:[
{
param:'xxx',
"createdAt": "2021-02-06T03:36:02.806Z",
"updatedAt": "2021-02-06T03:36:02.806Z"
}
]
}
but what I want is:
{
child:[
[
{
param:'xxx',
"createdAt": "2021-02-06T03:36:02.806Z",
"updatedAt": "2021-02-06T03:36:02.806Z"
}
]
]
}
then I tried the code:
#ModelOptions({ schemaOptions: { timestamps: true } })
class childModel {
#prop()
param:String
}
class parentModel {
#prop({type:[[childModel]]})
child:childModel[][]
}
saved like this parentModel.create( [ [ { param: 'xxx' } ] ] ) and result is:
{
child:[
[
{
param:'xxx'
}
]
]
}
No timestamps here,why?
I have seen some other similar problems, but I still don't understand ; maybe my English is too poor to understand, if you know, please tell me straightly.
Also Created an Issue on the typegoose Repo #485

Related

How to use filter expressions on aws using python3 for nested map attribute?

I have been trying to scan DynamoDB to check for particular value in a nested map attribute named deliverables. However using scan with filter expressions is resulting in an empty result.
import boto3
result = []
dynamo_client = boto3.client("dynamodb")
paginator = dynamo_client.get_paginator("scan")
operation_parameters = {
'FilterExpression': "#Deliverable= :deliverable",
'ExpressionAttributeNames': {
'#Deliverable': 'deliverables.fc986523-a666-478e-8303-2a1c3c1dc4ba'
},
'ExpressionAttributeValues': {
':deliverable': {
"M": {
"read": {
"BOOL": True
},
"upload": {
"BOOL": True
},
"write": {
"BOOL": True
}
}
}
}
}
for page in paginator.paginate(TableName="TableName", **operation_parameters):
result.append(page["Items"])
print(result)
The items in the dynamo db look like this:
[
[
{
"deliverables":{
"M":{
"7397d832-fefb-4ba2-97a1-0f6e73d611d9":{
"M":{
"read":{
"BOOL":true
},
"upload":{
"BOOL":true
},
"write":{
"BOOL":true
}
}
},
"fc986523-a666-478e-8303-2a1c3c1dc4ba":{
"M":{
"read":{
"BOOL":true
},
"upload":{
"BOOL":true
},
"write":{
"BOOL":true
}
}
}
}
},
"username":{
"S":"username1"
},
"deniedReferences":{
"L":[
]
}
},
{
"deliverables":{
"M":{
"7397d832-fefb-4ba2-97a1-0f6e73d611d9":{
"M":{
"read":{
"BOOL":true
},
"upload":{
"BOOL":false
},
"write":{
"BOOL":false
}
}
},
"fc986523-a666-478e-8303-2a1c3c1dc4ba":{
"M":{
"read":{
"BOOL":true
},
"upload":{
"BOOL":false
},
"write":{
"BOOL":false
}
}
}
}
},
"username":{
"S":"repositoryadmin"
},
"deniedReferences":{
"L":[
]
}
}
]
]
Please let me know if you can help me solve this issue.
The problem is the [dot] here: 'ExpressionAttributeNames': { '#Deliverable': 'deliverables.fc986523-a666-478e-8303-2a1c3c1dc4ba'}
Expressions docs: DynamoDB interprets a dot in an expression attribute name as a character within an attribute's name.
operation_parameters = {
"FilterExpression": "#D0.#D1=:deliverable", # the dot goes here!
"ExpressionAttributeNames": {
"#D0": "deliverables",
"#D1": "fc986523-a666-478e-8303-2a1c3c1dc4ba"
},

MongoDB updating array of objects does not work as expected

Got multiple documents in a db one of which looks like this:
{
"searchWord":[
"pizz",
"pizza"
],
"result":[
{
"idMeal":1,
"strMeal":"test1",
"strInstructions":"test1"
},
{
"idMeal":2,
"strMeal":"test2",
"strInstructions":"test2"
}
]
}
Tried to solve it like this:
eg:
db.meals.updateOne(
{
"searchWord": "pizz",
"result": { $elemMatch: { idMeal: "1" } }
},
{ $set: { 'result.$.strMeal' : "UPDATED" } }
)
This doesnt update the respective subdocument only the 2nd as if I wrote
{ $set: { 'result.1.strMeal' : "UPDATED" } }
(Which will result in the 2nd subdocument being updated)
This is the other idea (Same result)
db.meals.updateOne(
{ searchWord: "pizz", 'result.idMeal': 319012 },
{ $set: { "result.$.strMeal" : "fsdf" } }
)
What I dont seem to understand is its exactly the syntax that is provided by mongo yet it doesnt work
The "$" operator doesnt pick up which array of objects I wanna update
Try to use $[] in your $set for multiple positional element
db.collection.update({
"searchWord": "pizz"
},
{
$set: {
"result.$[r].strMeal": "UPDATED"
}
},
{
arrayFilters: [
{
"r.idMeal": 1
}
]
})
Here is the Mongo playground for your reference.

Elasticsearch create join field (Nodejs)

I have the following docs:
export class CustomerServiceResultType{
id: string;
body:{customerRelation: string};
}
export class CustomerType{
id: string;
body:{name: string};
}
I want CustomerServiceResultType to have a relation to CustomerType with the field: customerRelation.
this is my mapping:
await this.elasticsearchService.indices.putMapping({
"index": "db",
"type": "CustomerServiceResultType",
"body" : {
"properties": {
"customerRelation": {
"type": "join",
"relations": {
"CustomerServiceResultType": "CustomerType"
}
}
}
}
});
This is the error I get:
[Nest] 421512 - 11/21/2020, 6:40:42 PM [ExceptionsHandler] illegal_argument_exception +96414ms
ResponseError: illegal_argument_exception
There are no details about this error...
Thanks
There's nothing wrong with your request per-se -- I think it just requires one extra option: include_type_name: true.
It's undefined by default in nodejs but is required in ES 7.x on the server side. More reasoning behind this is here.
So this should do the trick:
await client.indices.putMapping({
include_type_name: true,
index: "db",
type: "CustomerServiceResultType",
body : {
properties: {
customerRelation: {
type: "join",
relations: {
CustomerServiceResultType: "CustomerType"
}
}
}
}
});
Typed indexes will be removed in 8.x so the best approach would actually be:
await client.indices.putMapping({
index: "db",
body : {
properties: {
customerRelation: {
type: "join",
relations: {
CustomerServiceResultType: "CustomerType"
}
}
}
}
});
BTW: your typescript types don't really play a role here because ES is a JSON-only interface and while there's the deprecated type aspect to ES, the two concepts are very distant.

Nested inside nested Objects with same key aggregation with another collection in mongoDB

Here I am placing example collections and expected output. I have nested modules array of objects
When I get request from the api as student Id, course id & module id then I have to send module % if exists if not need to send % as 0
Course collection
{
"_id": "courseId1",
"courseName": "course1",
"isActive": true,
"modules": [
{
"_id":"id1",
"name":"mod1",
"isActive": true
},
{
"_id":"id2",
"name":"mod2",
"isActive": true
},
{
"_id":"id3",
"name":"mod3",
"isActive": true
"modules":[
{
"_id":"id4",
"name":"mod4",
"isActive": true
},
{
"_id":"id5",
"name":"mod5",
"isActive": true,
"modules":[
{
"_id":"id6",
"name":"mod6",
"isActive": true
}
]
}
]
}
]
}
Course activity collection
{
"id":"ca1",
"studentId:"std1",
"courseId:"courseId1",
mProgress:[{
"id":"ac1",
"modId":"id5",
"studentID":"std1",
"progress":20
}
{
"id":"ac2",
"modId":"id4",
"studentID":"std1",
"progress":10
}
]
}
If I get studentID="std1" , courseId="5f698ca6f5cd3551060d86e8" , moduleId="id3"
I need response link below
modules:
[
{
"modId":"id4",
"name:"mod4",
"progress":10
},
{
"modId":"id5",
"name:"mod5",
"progress":0
}
]
I achieved this by java script. 1st I found course object using mongo query after that I search for nested object(i.e modules array) by using the following function
findNestedObj(keyToFind, valToFind,obj ) {
let foundObj;
JSON.stringify(obj , (_, nestedValue) => {
if (nestedValue && nestedValue[keyToFind] === valToFind) {
foundObj = nestedValue;
}
return nestedValue;
});
return foundObj;
}
var obj = 'here your object';
findNestedObj('_id','id3',obj );
Then I have calculated % from that

Mongoose - Query deeply nested Objects

I currently have a problem where I have to update entries in a deeply nested Document. Now to simplify my problem I have this example. Let's assume I store cars in my MongoDB. A Document would look like this
{
Make: "BMW",
Model: "3Series",
Wheels: [
{
_id: someObjectId
Size: "19 inch",
Screws: [
{
_id: someObjectId
Type : "M15x40"
},
{
_id: someObjectId
Type : "M15x40"
}
]
}
]
}
Now if I want to update a specific Wheel, my code would look somewhat like this
CarModel.findOneAndUpdate({
"_id": CarId, "Wheels._id": WheelId
}, {
"$set" : {
"Wheels.$.Size": NewSize
}
})
Now this works. But I am pretty lost on how I would update an specific screw as I am going through 2 Arrays. Any Idea how I could make this work?
You need arrayFilters functionality to define the path for more than one nested array:
CarModel.findOneAndUpdate(
{ "_id": CarId },
{ $set: { "Wheels.$[wheel].Screws.$[screw].Type": "something" } },
{ arrayFilters: [ { 'wheel._id': WheelId }, { 'screw._id': screwId } ] })

Resources