Geolocating polygons within a bounding box using MongoDB - javascript

I have an array of complex polygons stored in MongoDB and I am trying to fetch all the polygons which are partially/fully within a bounding box provided by the user.
A single polygon has an array of points with the structure
"points": [{"x": 8873, "y": 6394}, {"x": 8872, "y": 6395}, ...]
This is the schema I am working with:
const organoidSchema = new Schema({
type: String,
points: [{
x: Number,
y: Number
}],
id: String,
parents: Array,
children: Array,
accuracy: Number,
circularity: Number,
roundness: Number,
areaUm: Number,
majorAxisUm: Number,
minorAxisUm: Number,
aspectRatioAxis: Number,
averageDiameterUm: Number,
bounds: Array
})
I was looking into 2d indexing but I am not sure how to properly index the entire array and how to look for it afterwards...

Related

Parsing array of objects to format data

I have an array of cities with this structure (given from the CMS):
const cities = [
{
city: 'Genova',
coordinates: '{\'type\':\'Point\',\'coordinates\':[8.9473343,44.4023918]}',
countryIsoCode: 'it',
description: 'test',
isInitialCity: true,
}, {
city: 'Barcelona',
coordinates: '{\'type\':\'Point\',\'coordinates\':[2.0951271,41.3397004]}',
countryIsoCode: 'es',
description: 'description',
isInitialCity: false,
}, {
city: 'Sydney',
coordinates: '{type\':\'Point\',\'coordinates\':[151.2158203,-33.8704156]}',
countryIsoCode: 'au',
description: 'Sydney description',
isInitialCity: false,
}];
I want to parse the coordinates position to get a more scalable object and get its properties nesting.
This is what I've tried:
cities.map(city=>JSON.parse(city.coordinates))
But when I print it seems to have no effect. However, if I manually print a position like console.log(JSON.parse(cities[0].coordinates)) it shows a formatted result like is shown in the following screenshot:
How can I make it automatically via loop?
This is what I've tried:
cities.map(city=>JSON.parse(city.coordinates))
map() created you a brand new, separate array with the coordinates only, which you have thrown away afterwards.
However, if I manually print a position like console.log(JSON.parse(cities[0].coordinates)) [...] How can I make it automatically via loop?
Well, put it in a loop:
for(let city of cities)
city.coordinates = JSON.parse(city.coordinates);
However your example data is syntactically incorrect, there are ,}-s at the end of the objects (after the true/false), and the supposed JSON data is not JSON, like
{type':'Point','coordinates':[151.2158203,-33.8704156]}
^it has no pair, and it should be double quote anyway, all of them
{"type":"Point","coordinates":[151.2158203,-33.8704156]} <-- this is JSON
What I think might be happening is that you're doing the map right but not returning the result.
For example mynumbers.map(num => num++) won't actually effect mynumbers at all. You have to assign the result of the map to another variable...
const parsedCities = cities.map(city=>JSON.parse(city.coordinates))
Now your new parsedCities variable will look like you want it to and the original cities array will remain unchanged.
const cities = [
{
city: 'Genova',
coordinates: '{\'type\':\'Point\',\'coordinates\':[8.9473343,44.4023918]}',
countryIsoCode: 'it',
description: 'test',
isInitialCity: true,
}, {
city: 'Barcelona',
coordinates: '{\'type\':\'Point\',\'coordinates\':[2.0951271,41.3397004]}',
countryIsoCode: 'es',
description: 'description',
isInitialCity: false,
}, {
city: 'Sydney',
coordinates: '{type\':\'Point\',\'coordinates\':[151.2158203,-33.8704156]}',
countryIsoCode: 'au',
description: 'Sydney description',
isInitialCity: false,
}];
//for(let city of cities)
// city.coordinates = JSON.parse(city.coordinates);
var x=cities.map(city=>JSON.parse(JSON.stringify(city.coordinates)))
console.log("result :"+(JSON.stringify(x)))
// result :["{'type':'Point','coordinates':[8.9473343,44.4023918]}","{'type':'Point','coordinates':[2.0951271,41.3397004]}","{type':'Point','coordinates':[151.2158203,-33.8704156]}"]

Can I get only object of nested collection of parent object?

Hello I am wondering is it possible to get only one object of nested collection instead of whole object with nested collection of those objects which contains this object as a result of findOne query.
Let's say i have this model, Warrior model:
const classNameList = ['rogue', 'priest', 'warrior'];
const EquipmentSchema = new Schema({
weapon: String,
armor: String,
totalWeight: Number
});
const WarriorSchema = new Schema({
name: {
type: String,
required: true
},
class: {
type: String,
validate: {
validator: (value) => classNameList.includes(value),
message: 'This class does not exist!'
}
},
age: {
type: Number,
min: 18,
max: 1000,
required: true
},
weight: {
type: Number,
min: 18,
max: 150
},
equipments: [EquipmentSchema]
});
Then to find the only one equipment which total weight equals 12 I created this query :
const result = await Warrior.findOne({'equipments.totalWeight':12});
As a response of this query I am getting whole Warrior object with list of equipments but I only want to get this one Equipment which totalWeight equals 12. Is there any possibility to get only this one Equipment object via query?
I know that I can find this object with .find() method and assign it to the variable but it is not something what I am looking for.

Unable to properly convert array of complex objects to CSV

I have an array of complex objects, which may contain arrays of more objects. I want to convert these to a CSV file. Whenever there's a list of objects, the data is parsed as [object Object]. If a person has two emails, for example, I want to print these emails in two lines, and so on for each object. Addresses may be concatenated to one string, for example "France, Paris, someStreet 15".
The code is in this pen.
Here's the data:
var names = [
{
Name: [{First: "Peter", Last:"john"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 33.45,
Adress: [{Country:"UK", city: "London", street:"Oak", strtNumber:16},
{Country:"Italy", city: "MIlan", street:"Zabin", strtNumber:2}]
},
{
Name: [{First: "jack", Last:"Smith"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 30,
Adress: [{Country:"Portugal", city: "Lisbon", street:"crap", strtNumber:144},
{Country:"Greece", city: "Athenes", street:"Hercules", strtNumber:55}]
},
{
Name: [{First: "jon", Last:"snow"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 50,
Adress: [{Country:"Middle earth", city: "Winterfell", street:"raven", strtNumber:4345},
{Country:"Narnia", city: "Jacksonvile", street:"Great crap", strNumber:34}]
},
];
Right now this is the output:
The mistake is inside your converArrayOfObjectsToCSV-method, as the result of 'item[key]' is an array (in case of 'Name') and you need to specify further how to handle this array, as it otherwise will only be written out to [object Object].
You will have to access the element with i.e. item[key][index] and the iterate over its properties and print them as you need them.
The [object Object] indicates the data needs further conversion to get the desired output.
Here is an updated CodePen with an example conversion.
The conversion routine provided uses Object.values() to convert all data:
function parseArrayOfObjects(arrayOfObj){
return arrayOfObj.map(item =>
Object.values(item).join(" ")) // convert each array item to it's values
.join(" ") // convert final array to string
.replace(",", " "); // remove any commas to preserve csv format
}
Of course, your needs may dictate other conversions, so adjust as needed.

nested json data minipulation for ngx datatable in angualr -6 / js

I am trying to create a ngx datatable that creates columns dynamically from nested arrays, which with some research is not possible - so to achieve my desired result, I must flatten my nested arrays with the key / values that i need from each nested object into my parent object.
I need to manipulate my data so that my end result is a flat array and contains a line item for each object in the nested array earnings with 'abbreviation' being the key and 'amount' being the value..
I.e
[
{
employee_uuid: 978f37df-7e07-4118-be93-d82507ce5c46,
employee_code: JB00024,
full_name: Thulisile Sandra,
last_name: Bhekiswayo
earnings:[{
abbreviation: "NT HRS"
amount: "45.00"
money: false
name: "Normal Time HRS"
time: true
unique: "7d783469-717e-408a-bc3c-93115cb632dd_true"
uuid: "7d783469-717e-408a-bc3c-93115cb632dd"
value: "45.00"
},
{
abbreviation: "OT HRS"
amount: "25.00"
money: false
name: "Normal Time HRS"
time: true
unique: "7d783469-717e-408a-bc3c-93115cb632dd_true"
uuid: "7d783469-717e-408a-bc3c-93115cb632dd"
value: "45.00"
}],
terminated false
}
...
]
I'd like to look like this:
[
{
employee_uuid: 978f37df-7e07-4118-be93-d82507ce5c46,
employee_code: JB00024,
full_name: Thulisile Sandra,
last_name: Bhekiswayo,
NT HRS: '45.00',
OT HRS, '25.00',
terminated:false
}
...
]
I am not sure how to go about this, I've tried reducing and map functions but no success.. I can add the nested arrays to the parent object with Object.assign but that takes the whole object, I need to create a new parameter from that object..
Any help would be hugely appreciated..
You can use es6 destructuring for this, simply expose whatever properties you need and then "recompose" then into the object shape you want.
For example:
return myEmployeeArray.map(employee => {
const {earn } = employee
earn.map(field => field.abbreviation)
myDesiredObject = { fieldA: employee.abbreviation....fieldE:field.abbreviation}
}
This would get you one of your nested fields

Map in Mongoose

I'm trying to create a schema in Mongoose that have a map (object, associative array, key-value pairs), but no success so far.
The documents of my schema must be something like this:
{
"_id": ObjectId("..."),
"groups"
{
"groupA":
{
"value1": "...",
"value2": "..."
},
"groupB":
{
"value3": "...",
},
"groupC":
{
"value4": "...",
"value5": "...",
},
...
}
}
groups is as object with a variable number of keys. I don't know those keys ahead of time as it'll be create by the user.
Every entry in groups is another object. As before, I don't know the key identifiers, but I know that the values are String (or Boolean, or Number, doesn't matter).
Of course, those keys are Strings.
Is it even possible (is there anyway to build such schema/model) in Mongoose?
Best practice is to keep any dynamic data out of your field names. The typical approach for a use case like this is to make groups an array and move the name of the group into a name field of the contained objects. Then you can use the Mixed type to contain the user-defined set of values:
{
"_id": ObjectId("..."),
"groups":
[
{
name: "groupA",
values: {
"value1": "...",
"value2": "..."
}
},
{
name: "groupB",
values: {
"value3": "..."
}
},
{
name: "groupC",
values: {
"value4": "...",
"value5": "..."
}
},
...
]
}
You'd define the schema as:
var schema = new Schema({
groups: [{
name: String,
values: Schema.Types.Mixed
}]
});
Map is supported from version 5.1 -
http://mongoosejs.com/docs/schematypes.html#maps
Looks like somebody made a plugin, Hooray!
https://www.npmjs.com/package/mongoose-map
Once you install and configure according to the readme you can just do {groups:[MongooseMap]}...
Have you tried something like this:
var schema = new mongoose.Schema({
groups: [mongoose.Schema.Types.Mixed]
});
Reference: Mongoose Schema Types
Edit, given my comments below, and riffing on the answer before mine, let's assume that all values are of type string (I had understood that they might be anything):
var schema = new mongoose.Schema({
groups:[{
name: String,
values:[String]
}]
});
Edit #2: Assuming that "value1" is a placeholder for some more meaningful name and assuming that the number of member names is finite, as long as they are not required, then you can put them all in your schema, so instead of the array version, you should be able to do this:
var schema = new mongoose.Schema({
groups:[{
name: String,
value1: String,
value2: String,
value3: String,
value4: String,
value5: String
}]
});

Categories

Resources