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
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"
},
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.
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.
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
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 } ] })