I know this question pops up quite a bit and I have tried researching the issue before posting but still do not know what I am missing
I have a schema with nested objects. My schema is expecting a company property to be an object. There are required properties on that object, but they are being ignored. Why is it ignoring the required properties?
Schema:
{
'business_type': {
'type': 'string',
"enum": ['company', 'non_profit']
},
'email': {
'type': 'string'
},
'company': {
'type': 'object',
'properties': {
'address': {
'type': 'object',
'properties': {
'city': {
'type': 'string',
},
'country': {
'type': 'string',
'enum': ['US']
},
'line1': {
'type': 'string'
},
'line2': {
'type': 'string'
},
'postal_code': {
'type': 'string'
},
'state': {
'type': 'string'
}
},
'required': ['city', 'country', 'line1', 'postal_code', 'state'],
},
'name': {
'type': 'string'
},
'phone': {
'type': 'string'
}
},
'required': ['address', 'name', 'phone'],
},
'required' : ['business_type', 'email', 'company']
}
Example object that does not fail but should because it is missing the phone property
{
"business_type": "company",
"email": "email#email.com",
"company": {
"address": {
"city": "city",
"country": "US",
"line1": "line1",
"line2": "line2",
"postal_code": "00000",
"state": "AZ"
},
"name": "name"
}
}
The validation works fine if it is missing either business_type, email, or company so it's not validating the nested structure.
I'm assuming I'm overlooking something, I just don't know what it is I'm overlooking
You need to wrap business_type, email, and company in a properties keyword. Otherwise the schema doesn't consider them to be properties, just extra data in the schema. JSON Schema will ignore keywords it doesn't know.
You have it correct in the company subschema.
Related
so here is my stories model,
const storySchema = new mongoose.Schema(
{
avatar: { type: String, default: null },
handle: { type: String, default: null },
new: { type: Boolean, default: true },
isLive: {type: Boolean, default: false},
url: { type: String },
type: { type: String },
userName: { type: String, default: null },
userId: { type: mongoose.Schema.Types.ObjectId, ref: "user_details" },
isDeleted: { type: Boolean, default: false}
},
{
timestamps: true,
minimize: false
}
)
userId is refered to user_details, so currently when i list stories they get listed like this ,
one story at a time and sorted by userId and createdAt,
As you can see the first 2 stories has the same userId, and what i want to do is that i group the stories by the user Object.
"status": true,
"data": [
{
"_id": "633564ab793cf2a65f7c5dad",
"avatar": null,
"handle": null,
"new": true,
"isLive": false,
"url": "https://ellingsen-group.s3.amazonaws.com/media-1664443562856.png",
"type": "",
"userName": null,
"userId": "62eb5d58512ef25f1352830b",
"isDeleted": false,
"createdAt": "2022-09-29T09:26:03.846Z",
"updatedAt": "2022-09-29T09:26:03.846Z",
"__v": 0
},
{
"_id": "633564a9793cf2a65f7c5daa",
"avatar": null,
"handle": null,
"new": true,
"isLive": false,
"url": "https://ellingsen-group.s3.amazonaws.com/media-1664443559395.png",
"type": "",
"userName": null,
"userId": "62eb5d58512ef25f1352830b",
"isDeleted": false,
"createdAt": "2022-09-29T09:26:01.032Z",
"updatedAt": "2022-09-29T09:26:01.032Z",
"__v": 0
},
{
"_id": "633564e6793cf2a65f7c5dba",
"avatar": null,
"handle": null,
"new": true,
"isLive": false,
"url": "https://ellingsen-group.s3.amazonaws.com/media-1664443621607.png",
"type": "",
"userName": null,
"userId": "6290a0e7f03b0b3585e0f740",
"isDeleted": false,
"createdAt": "2022-09-29T09:27:02.608Z",
"updatedAt": "2022-09-29T09:27:02.608Z",
"__v": 0
},
{
"_id": "633564bf793cf2a65f7c5db0",
"avatar": null,
"handle": null,
"new": true,
"isLive": false,
"url": "https://ellingsen-group.s3.amazonaws.com/media-1664443582519.png",
"type": "",
"userName": null,
"userId": "6290a0e7f03b0b3585e0f740",
"isDeleted": false,
"createdAt": "2022-09-29T09:26:23.519Z",
"updatedAt": "2022-09-29T09:26:23.519Z",
"__v": 0
}
],
"totalPages": 1,
"message": "Get user story Feed Success"
want to change this, so for user 1 ( story 1, 2, 3) user 2 ( story 1,2 ) etc,
here is the query for the result above.
const stories: any = await Story.StoryModel.aggregate([{ $match: { '_id': { $in: combined } } }, { $sort: { userId: -1, createdAt: -1 } }, listStoriesFacetPagination]).exec()
I tried grouping them like this (below) but i get at error saying that stories.groupBy is not a function, I'm stuck at this point and been trying to work this out for the past week.
const groupByUserId = stories.groupBy((userId: any) => {
return story.userId;
});
and it would not work.
You can achieve this by using reduce method, the code will be like this:
const list = [{
'name': 'John',
'userId': '1',
},
{
'name': 'Anne',
'userId': '2',
},
{
'name': 'John',
'userId': '1',
},
{
'name': 'Anne',
'userId': '2',
},
];
const groups = list.reduce((groups, item) => ({
...groups,
[item.userId]: [...(groups[item.userId] || []), item]
}), {});
This code will result in a object like this:
{
"1": [
{'name': 'John', 'userId': '1'},
{'name': 'John', 'userId': '1'}
],
"2": [
{'name': 'Anne', 'userId': '2'},
{'name': 'Anne', 'userId': '2'}
]
}
Hope it help you :D
Here is the solution i found,
const stories: any = await Story.StoryModel.aggregate([
{ $match: { '_id': { $in: combined } } },
{ $group: {
_id: '$userId',
stories: { $push: { url: '$url', _id: '$_id' , isLive: '$isLive', avatar: '$avatar', type:'$type', handle:'$handle', new:'$new', userName:'$userName', userId:'$userId', isDeleted:'$isDeleted', createdAt:'$createdAt' } } } },
{ $sort: { createdAt: 1 } },
listStoriesFacetPagination]).exec()
How to make python script result to become a variable. Ans use that variable into a value of another python script. I want to insert the result "ImageId" and insert in the " client.create_launch_template"
For example:
import boto3
from dateutil import parser
def newest_image(list_of_images):
latest = None
for image in list_of_images:
if not latest:
latest = image
continue
if parser.parse(image["CreationDate"]) > parser.parse(latest["CreationDate"]):
latest = image
return latest
client = boto3.client("ec2", region_name="ap-southeast-1")
filters = [
{"Name": "description", "Values": ["poc ami"]},
{"Name": "owner-id", "Values": ["144970827735"]},
{"Name": "state", "Values": ["available"]},
]
response = client.describe_images(Filters=filters)
source_image = newest_image(response["Images"])
print(source_image['ImageId'])
response = client.create_launch_template(
DryRun=False,
ClientToken='string',
LaunchTemplateName='string',
VersionDescription='string',
LaunchTemplateData={
'KernelId': 'string',
'EbsOptimized': True|False,
'IamInstanceProfile': {
'Arn': 'string',
'Name': 'string'
},
'BlockDeviceMappings': [
{
'DeviceName': 'string',
'VirtualName': 'string',
'Ebs': {
'Encrypted': True|False,
'DeleteOnTermination': True|False,
'Iops': 123,
'KmsKeyId': 'string',
'SnapshotId': 'string',
'VolumeSize': 123,
'VolumeType': 'standard'|'io1'|'gp2'|'sc1'|'st1'
},
'NoDevice': 'string'
},
],
'NetworkInterfaces': [
{
'AssociatePublicIpAddress': True|False,
'DeleteOnTermination': True|False,
'Description': 'string',
'DeviceIndex': 123,
'Groups': [
'string',
],
'InterfaceType': 'string',
'Ipv6AddressCount': 123,
'Ipv6Addresses': [
{
'Ipv6Address': 'string'
},
],
'NetworkInterfaceId': 'string',
'PrivateIpAddress': 'string',
'PrivateIpAddresses': [
{
'Primary': True|False,
'PrivateIpAddress': 'string'
},
],
'SecondaryPrivateIpAddressCount': 123,
'SubnetId': 'string'
},
],
'ImageId': '**ImageId**', ### I need to paste here the result
'InstanceType': '**InstanceType**', ### I need to paste here the result
'KeyName': 'string',
'Monitoring': {
'Enabled': True|False
},
'Placement': {
'AvailabilityZone': 'string',
'Affinity': 'string',
'GroupName': 'string',
'HostId': 'string',
'Tenancy': 'default'|'dedicated'|'host',
'SpreadDomain': 'string'
},
'RamDiskId': 'string',
'DisableApiTermination': True|False,
'InstanceInitiatedShutdownBehavior': 'stop'|'terminate',
'UserData': 'string',
'TagSpecifications': [
{
'ResourceType': 'client-vpn-endpoint'|'customer-gateway'|'dedicated-host'|'dhcp-options'|'elastic-ip'|'fleet'|'fpga-image'|'host-reservation'|'image'|'instance'|'internet-gateway'|'launch-template'|'natgateway'|'network-acl'|'network-interface'|'reserved-instances'|'route-table'|'security-group'|'snapshot'|'spot-instances-request'|'subnet'|'traffic-mirror-filter'|'traffic-mirror-session'|'traffic-mirror-target'|'transit-gateway'|'transit-gateway-attachment'|'transit-gateway-route-table'|'volume'|'vpc'|'vpc-peering-connection'|'vpn-connection'|'vpn-gateway',
'Tags': [
{
'Key': 'string',
'Value': 'string'
},
]
},
],
'ElasticGpuSpecifications': [
{
'Type': 'string'
},
],
'ElasticInferenceAccelerators': [
{
'Type': 'string'
},
],
'SecurityGroupIds': [
'string',
],
'SecurityGroups': [
'string',
],
'InstanceMarketOptions': {
'MarketType': 'spot',
'SpotOptions': {
'MaxPrice': '',
'SpotInstanceType': 'persistent',
'BlockDurationMinutes': 123,
'ValidUntil': datetime(2015, 1, 1),
'InstanceInterruptionBehavior': 'stop'
}
},
'CreditSpecification': {
'CpuCredits': 'string'
},
'CpuOptions': {
'CoreCount': 123,
'ThreadsPerCore': 123
},
'CapacityReservationSpecification': {
'CapacityReservationPreference': 'open'|'none',
'CapacityReservationTarget': {
'CapacityReservationId': 'string'
}
},
'LicenseSpecifications': [
{
'LicenseConfigurationArn': 'string'
},
],
'HibernationOptions': {
'Configured': False
}
},
TagSpecifications=[
{
'ResourceType': 'client-vpn-endpoint'|'customer-gateway'|'dedicated-host'|'dhcp-options'|'elastic-ip'|'fleet'|'fpga-image'|'host-reservation'|'image'|'instance'|'internet-gateway'|'launch-template'|'natgateway'|'network-acl'|'network-interface'|'reserved-instances'|'route-table'|'security-group'|'snapshot'|'spot-instances-request'|'subnet'|'traffic-mirror-filter'|'traffic-mirror-session'|'traffic-mirror-target'|'transit-gateway'|'transit-gateway-attachment'|'transit-gateway-route-table'|'volume'|'vpc'|'vpc-peering-connection'|'vpn-connection'|'vpn-gateway',
'Tags': [
{
'Key': 'string',
'Value': 'string'
},
]
},
]
)
So all in all I can get the values of the string but its not clear to me how to use that values to next command.
I want to use JSON schema validator for Validation while i using code like following i get the error gCode is not defined
I tried like following code
properties: {
oemId: {
'type': ['integer'],
'minLength': 1,
'required': true
},
gCode:{
'type': ['string'],
'minLength': 1
},
problemCategoryId: {
'type': ['integer'],
'minLength': 1
}
},
if :{
properties:{
oemId: 1
}
},
then:{
required:[gCode]
},
else:{
required: [problemCategoryId]
}
I expected when oemId=1 then gCode is required=true else problemCategoryId is required true
The if-then-else statement of the JSON Schema in question is incorrect. Here is the correct one:
{
"type": "object",
"properties": {
oemId: {
'type': ['integer'],
'minLength': 1,
'required': true
},
gCode:{
'type': ['string'],
'minLength': 1
},
problemCategoryId: {
'type': ['integer'],
'minLength': 1
}
},
"if": {
"properties": {
"oemId": { "const": 1 }
},
"required": ["oemId"]
},
"then": { "required": ["gCode"] },
"else": { "required": ["problemCategoryId"] }
}
Please note this if-then-else syntax is just added to JSON Schema in draft-07, and here its document in json-schema.org: https://json-schema.org/understanding-json-schema/reference/conditionals.html
I have student collection of mongo documents like the following:
{
name: 'XYZ',
age: 26,
education: [
{ title: 'abc', university: 'pqr', grade: 'A' },
{ title: 'def', university: 'uvq', grade: 'B' },
{ title: 'ghi', university: 'xyz', grade: 'A' },
{ title: 'jkl', university: 'pqr', grade: 'B' },
{ title: 'mno', university: 'uvw', grade: 'C' }
]
}, {
name: 'QQQ',
age: 26,
education: [
{ title: 'abc', university: 'pqr', grade: 'A' },
{ title: 'ghi', university: 'xyz', grade: 'A' },
{ title: 'jkl', university: 'xyz', grade: 'B' },
{ title: 'mno', university: 'pqr', grade: 'C' }
]
}
Now I want to write a query in which I want students who MUST HAVE completed their
{education-title:'abc' with grade A} OR {education-title:'def'
with grade B}
BUT MUST NOT have completed
{education-title:'jkl' with university:pqr}
AND{education-title:'mno' with university:uvw}
If observed carefully my document with the name: QQQ satisfies all the criteria and should be the output of the query. I'm trying to solve these conditions by using $or and $and operators inside $elemMatch operator, but not sure whether my approach is correct or not. My query looks like the following
studentModel.aggregate({
{
$match: {
'education': $elemMatch: {
$or: [{
'title': 'abc',
'grade': 'A'
},
{
'title': 'def',
'grade': 'B'
}
]},
$not: {
$elemMatch: {
$and: [{
'title': 'jkl',
'university': 'pqr'
},
{
'title': 'mno',
'university': 'uvw'
}
]
}
}
}
});
above code is working and giving me the output but I'm not sure if it will work with millions of record and still produce the expected output or not. I just wanna make sure if my approach of using $and AND $or operator inside $elemMatch is correct or not?
When I run your query it incorrectly selects the first document, and that is because the second condition inside the $not actually can never match an element since it is not possible for $elemMatch to contain "multiple conditions" for the same properties on the same element. Which is what $elemMatch is making the distinction of in "matching multiple conditions on the same array element". Hence the naming.
The correct way, is instead to list "separate" $elemMatch statements and wrap them with $all:
db.getCollection('students').find({
"education": {
"$elemMatch": {
"$or": [
{ "title": "abc", "grade": "A" },
{ "title": "def", "grade": "B" }
]
},
"$not": {
"$all": [
{ "$elemMatch": {
"title": "jkl", "university": "pqr"
}},
{ "$elemMatch": {
"title": "mno", "university": "uvw"
}}
]
}
}
})
This correctly only selects the second QQQ document from the provided samples.
I'm trying to render two templates together using the compositeTemplates attribute. However only the second one gets included. I believe this structure is correct because I can get one or the other if I just comment one out. According to the documentation all I should need to set is the sequence. How can I get both server templates to be included in one envelope?
'emailSubject': "test doc",
'emailBurb': 'this is a test doc',
'status': 'sent',
'compositeTemplates': [{
'serverTemplates': [
# LT
{
'sequence': '1',
'templateId': '9FA06158-4789-4473-B435-F81BF2C7D1D0',
},
],
'serverTemplates': [
# ST
{
'sequence': '2',
'templateId': '235E5E2C-D4F1-4043-AE7E-793DD89268F3',
},
],
'inlineTemplates': [{
'sequence': '1',
'recipients': {
'signers': [{
'email': send_to,
'name': "Tester",
'recipientId': '1',
'roleName': 'Signer',
'tabs': {
'textTabs': [
{
'tabLabel': 'full_address',
'value': 'Massachusetts'
},
],
},
}],
},
}],
'inlineTemplates': [{
'sequence': '2',
'recipients': {
'signers': [{
'email': send_to,
'name': "Tester",
'recipientId': '1',
'roleName': 'Signer',
'tabs': {
'textTabs': [
{
'tabLabel': 'full_address',
'value': 'Massachusetts'
},
],
},
}],
},
}],
}]
The request you have there is actually combining the two server-templates. The sequence in this case determines which documents/recipients take priority. To included them both as a separate documents, you'd want something more like the below. This has two composite templates. Each one combines a server-side template with an in-line template. I haven't tested this, but it should get you going.
'emailSubject': "test doc",
'emailBurb': 'this is a test doc',
'status': 'sent',
'compositeTemplates': [{
'serverTemplates': [
# LT
{
'sequence': '1',
'templateId': '9FA06158-4789-4473-B435-F81BF2C7D1D0',
},
],
'inlineTemplates': [{
'sequence': '2',
'recipients': {
'signers': [{
'email': send_to,
'name': "Tester",
'recipientId': '1',
'roleName': 'Signer',
'tabs': {
'textTabs': [
{
'tabLabel': 'full_address',
'value': 'Massachusetts'
},
],
},
}],
},
}]
},
{
'serverTemplates': [
# ST
{
'sequence': '1',
'templateId': '235E5E2C-D4F1-4043-AE7E-793DD89268F3',
},
],
'inlineTemplates': [{
'sequence': '2',
'recipients': {
'signers': [{
'email': send_to,
'name': "Tester",
'recipientId': '1',
'roleName': 'Signer',
'tabs': {
'textTabs': [
{
'tabLabel': 'full_address',
'value': 'Massachusetts'
},
],
},
}],
},
}],
}]