There's a requirement to search some locations in a given region. And here is an example of my test data in mongo:
{
"_id" : "insititution_NPqTrcysjKV",
"phone" : "18080808088",
"name" : "Insititution 1",
"address" : "xxxxxxxxxxxxx",
"city" : "New York",
"location" : {
"type" : "Point",
"coordinates" : [
121.62764,
29.89805
]
},
"includeLessions" : [
"English"
]
}
I've got a list of such entries in my mongodb. and here goes my query in Robo3T:
db.Insititution.find(
{
location: {
$geoIntersects: {
$geometry: {
type: "Polygon" ,
coordinates: [
[ [ 121.33, 29.899 ], [ 121.33, 29.770 ], [ 121.67, 29.770 ], [ 121.67, 29.899 ], [ 121.33, 29.899 ] ]
]
}
}
}
}
)
It's works in robo3t, but in my project, I did like this:
var where = {
location: {
$geoIntersects: {
$geometry: {
type: "Polygon",
coordinates: [
[longitudeMin, latitudeMin],
[longitudeMin, latitudeMax],
[longitudeMax, latitudeMax],
[longitudeMax, latitudeMin],
[longitudeMin, latitudeMin]
]
}
}
}
}
return promiseUtils.mongoNativeFindPromise(this.modelName, where);
// function in promiseUtils:
exports.mongoNativeFindPromise = async function (modelName, where, options) {
const db = await MongoClient.connect(uri);
try {
let collection = db.db(mongoDBSettings.database);
var cusor = await collection.collection(modelName).find(where, options);
return await cusor.toArray();
} catch (err) {
throw err;
} finally {
db.close();
}
};
and this is exactly what the 'where' variable goes like when run the code:
but mongo return an error: GeoJSON coordinates must be an array
Can anybody help?
Related
In mongoose when i call find() function and update inside the find finction , the function iterate but data is not inserted into subarray it is inserted into root array.
this is my code
for (let k in listMed) {
insertUpdate(listMed[k]);
}
Function
function insertUpdate(med) {
StockDB.findOne({ Medicine_name: med.Medicine_name }, function (err, element) {
if (err) {
console.log(err);
}
else {
console.log(element);
if (element != null) {
element.MRP = med.MRP;
element.Rate = (parseFloat(med.MRP) / parseFloat(med.PerCount));
element.Items.push({
Batch_no: med.Batch_no,
Exp_date: med.ExpDate,
Quantity: med.PerCount
});
element.save();
}
else {
StockDB.insertMany({
Medicine_name: med.Medicine_name,
MRP: med.MRP,
Rate: (parseFloat(med.MRP) / parseFloat(med.PerCount)),
Items: [{
Batch_no: med.Batch_no,
Exp_date: med.ExpDate,
Quantity: med.PerCount
}]
});
}
}
});}
I want to store like this
[
{
Medicine_name: "Rantac 150",
Price : "30",
Items : [
{
Batch_no : b123,
Expiry_date : 22-02-2028,
}
{
Batch_no : b113,
Expiry_date : 12-05-2027,
}
{
Batch_no : b153,
Expiry_date : 20-01-2024,
}
]
}
]
But it is srore the data like this
[
{
Medicine_name: "Rantac 150",
Price : "30",
Items : [
{
Batch_no : b123,
Expiry_date : 22-02-2028,
}
]
}
{
Medicine_name: "Rantac 150",
Price : "30",
Items : [
{
Batch_no : b113,
Expiry_date : 12-05-2027,
}
]
}
{
Medicine_name: "Rantac 150",
Price : "30",
Items : [
{
Batch_no : b153,
Expiry_date : 20-01-2024,
}
]
}
]
object is not push into the items array , it repeatedliy call insert function but 1st time when inserted element will be not null but it is still null
I am trying to filter the lat and long with maximum distance 10km.
Here is my nodejs mongodb code implementation:
dbo.collection('CT').createIndex( { "loc" : "2dsphere" } );
var findquery = {
"GeoJSON.loc": {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 103.819839, 1.352083], //Long Lat
$maxDistance:10000
}
}
}
};
dbo.collection("CT").find(findquery).toArray(function(err, result) {
console.log(result);
db.close();
});
Data has stored like this mongodb:
[ {
"_id": "5bc04226df7ea7503c7d57f1",
"results": [
{
"ID": "FD02328677"
}
],
"GeoJSON": [
{
"city": "Los Angeles",
"loc": {
"type": "Point",
"coordinates": [
-118.24532,
34.05349
]
}
},
{
"city": "Tampa",
"loc": {
"type": "Point",
"coordinates": [
-82.45927,
27.94653
]
}
},
{
"city": "Seattle",
"loc": {
"type": "Point",
"coordinates": [
-122.32945,
47.60358
]
}
}
] } ]
When I run the code, I can get the result (by right I shouldn't), it looks like filter function is not working on my code. Any suggestion?
Just a few typos:
The index
dbo.collection('CT').createIndex( { "loc" : "2dsphere" } );
should be
dbo.collection('CT').createIndex( { "GeoJSON.loc" : "2dsphere" } );
Otherwise you get an error running your query.
The query
var findquery = {
"GeoJSON.loc": {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 103.819839, 1.352083], //Long Lat
$maxDistance:10000
}
}
}
};
should be
var findquery = {
"GeoJSON.loc": {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 103.819839, 1.352083], //Long Lat
},
$maxDistance:10000
}
}
};
In your query the $maxDistance within $geometry is ignored. There are no $maxDistance in $near so all records are returned.
I have such document structure:
{
favourite_shops: [
{
shop_id: "5961352278cba91cc6a6e8cc",
time: "2017-07-11T14:43:35.465Z"
},
{
shop_id: "5964e446c15c760f9b646d99",
time: "2017-07-11T14:44:40.429Z"
},
{
shop_id: "5964e446c15c760f9b646d98",
time: "2017-07-11T14:44:50.988Z"
}
]
}
How can I transform this to something like this:
{
favourite_shops: [
"5961352278cba91cc6a6e8cc",
"5964e446c15c760f9b646d99",
"5964e446c15c760f9b646d98"
]
}
You can $map on the array itself and get only the fields you need. (This is done within the query itself not after you receive the documents)
example.
given documents;
> db.Shopping.find().pretty()
{
"_id" : ObjectId("59651ce38828356e1a39fde9"),
"favourite_shops" : [
{
"shop_id" : "5961352278cba91cc6a6e8cc",
"time" : "2017-07-11T14:43:35.465Z"
},
{
"shop_id" : "5964e446c15c760f9b646d99",
"time" : "2017-07-11T14:44:40.429Z"
},
{
"shop_id" : "5964e446c15c760f9b646d98",
"time" : "2017-07-11T14:44:50.988Z"
}
]
}
{
"_id" : ObjectId("59665cf3d8145b41e5d2f5da"),
"favourite_shops" : [
{
"shop_id" : "2222",
"time" : "2017-07-11T14:43:35.465Z"
},
{
"shop_id" : "4444",
"time" : "2017-07-11T14:44:40.429Z"
},
{
"shop_id" : "6666",
"time" : "2017-07-11T14:44:50.988Z"
}
]
}
$map on favourite_shops array ({$match} block is optional, you can remove if you want shopping id for all documents)
> db.Shopping.aggregate([[
{
"$match": {
"_id": ObjectId("59651ce38828356e1a39fde9")
}
},
{
"$project": {
"my_favourite_shops": {
"$map": {
"input": "$favourite_shops",
"as": "each_shop",
"in": "$$each_shop.shop_id"
}
}
}
}
]).pretty()
{
"_id" : ObjectId("59651ce38828356e1a39fde9"),
"my_favourite_shops" : [
"5961352278cba91cc6a6e8cc",
"5964e446c15c760f9b646d99",
"5964e446c15c760f9b646d98"
]
}
And, with mongodb 3.4.4, I simply could $project on nested field,
db.Shopping.aggregate([{"$project": {"my_favourite_shops": "$favourite_shops.shop_id"}}]).pretty()
{
"_id" : ObjectId("59651ce38828356e1a39fde9"),
"my_favourite_shops" : [
"5961352278cba91cc6a6e8cc",
"5964e446c15c760f9b646d99",
"5964e446c15c760f9b646d98"
]
}
{
"_id" : ObjectId("59665cf3d8145b41e5d2f5da"),
"my_favourite_shops" : [
"2222",
"4444",
"6666"
]
}
Assuming we have such data structure:
const data = {
favourite_shops: [
{
shop_id: "5961352278cba91cc6a6e8cc",
time: "2017-07-11T14:43:35.465Z"
},
{
shop_id: "5964e446c15c760f9b646d99",
time: "2017-07-11T14:44:40.429Z"
},
{
shop_id: "5964e446c15c760f9b646d98",
time: "2017-07-11T14:44:50.988Z"
}
]
};
Just a bit of ES6 magic:
const result = {
favourite_shops: []
};
data.favourite_shops.forEach(el => result.favourite_shops.push(el.shop_id));
Second elegant approach:
const result = {
favourite_shops: data.favourite_shops.map(el => el.shop_id)
};
I'm starting with mongodb, I'm using aggregate function which gives me the last user of the last element into the sampleStatus array. (I mean the latest record added to sampleStatus)
I have a collection of samples like this :
{
"_id" : ObjectId("58d6cbc14124691cd8154d72"),
"correlativeCode" : "CSLLPA53E20M017W",
"registrationMethod" : "taken",
"originPlace" : "SOMEPLACE",
"temperature" : 16,
"sampleStatus" : [
{
"nameStatus" : "status1",
"place" : "place1",
"rejectionReason" : "Nothing",
"user" : "user1",
"_id" : ObjectId("58d6cbc14124691cd8154d73")
},
{
"nameStatus" : "status2",
"place" : "place2",
"rejectionReason" : "Nothing",
"user" : "user4",
"_id" : ObjectId("58d6cbc14124691cd8154d73")
},
{
"nameStatus" : "status3",
"place" : "place3",
"rejectionReason" : "Nothing",
"user" : "user3",
"_id" : ObjectId("58d6cbc14124691cd8154d73")
},
{
"nameStatus" : "status4",
"place" : "place4",
"rejectionReason" : "Nothing",
"user" : "user1",
"_id" : ObjectId("58d6cbc14124691cd8154d73")
},
{
"nameStatus" : "status5",
"place" : "place5",
"rejectionReason" : "Nothing",
"user" : "user5",
"_id" : ObjectId("58d6cbc14124691cd8154d73")
}
]
}
This is the function I'm using:
db.collection.aggregate([
{ "$match": { "correlativeCode": "CSLLPA53E20M017W" } },
{ "$redact": {
"$cond": [
{ "$eq": [
{ "$let": {
"vars": {
"item": { "$arrayElemAt": [ "$sampleStatus", -1 ] }
},
"in": "$$item.user"
} },
"user5"
] },
"$$KEEP",
"$$PRUNE"
]
}}
])
When I use this in mongodb's console, it works.. but, when I try to adapt this in a controller.js
VerifySample: function (req, res) {
var id = req.body.idSample;
var idUser=req.body.currentuser;
SamplePatientModel.aggregate([
{ $match: { _id: id } },
{ $redact: {
$cond: [
{ $eq: [
{ $let: {
vars: {
"item": { $arrayElemAt: [ "$sampleStatus", -1 ] }
},
in: "$$item.user"
} },
idUser
] },
"$$KEEP",
"$$PRUNE"
]
}}
],
function(err, _SamplePatient) {
console.log('entry function');
if (err) {
console.log('Entry err');
return res.status(500).json({message: 'Error SamplePatient', error: err});
}
//No results
if(!_SamplePatient){
console.log('no results ');
return res.status(404).json({message: 'error', error: err});
}
console.log('Got it');
console.log(_SamplePatient);
return res.status(200).json(_SamplePatient);
}
);}
It gives me following response:
[]
console.log(_SamplePatient) doesn't show anything
the words "entry function" are printed in console
what am I doing wrong?
Please, help me.
Thanks.
Casting ObjectId in mongoose is not supported in aggregation pipeline.
So you've to explicitly cast the string value to ObjectId in the aggregation pipeline.
Update your match stage to below.
{ $match: { _id: mongoose.Types.ObjectId(req.body.idSample) } }
Here is the issue
https://github.com/Automattic/mongoose/issues/1399
Mongoose Docs:
http://mongoosejs.com/docs/api.html#model_Model.aggregate
Here is my User Schema
{
"user_collection":[
{
"_id":"xxx",
"name":"NAME",
"prescription":
{
"doctor_id":
[{
"_id":"xxx",
"medicine_id":"MEDICINE_ID",
}]
},
"meal":{
"meal_name":{
"start_time":"START_TIME",
"end_time":"END_TIME"
}
},
"created_at":"CREATED_AT",
"updted_at":"UPDATED_AT"
}
]
}
Note : _id given just for understanding
I need to insert document inside the prescription array. Here is the condition
If the new doctor_id is given, it should add in the prescription array like
{
"_id" : ObjectId("5813288eaa0f1231de477d92"),
"name" : "andrew",
"prescription" : [
{
"prescription" : [
{
"_id" : ObjectId("58143d484e26a229873b0528"),
"medicine_id" : "10011241343"
}
],
"_id" : ObjectId("58143d484e26a229873b0527"),
"doctor_id" : "5813221ace684e2b3f5f0a6d"
}
]
}
And if i given the doctor_id that already exists it should add like
{
"_id" : ObjectId("5813288eaa0f1231de477d92"),
"name" : "andrew",
"prescription" : [
{
"prescription" : [
{
"_id" : ObjectId("58143d484e26a229873b0528"),
"medicine_id" : "10011241343"
}
],
"prescription" : [
{
"_id" : ObjectId("58143d484e26a229873b0529"),
"medicine_id" : "10011241349"
}
],
"_id" : ObjectId("58143d484e26a229873b0527"),
"doctor_id" : "5813221ace684e2b3f5f0a6d"
}
]
}
What i have tried is
dbModel.user.update({
_id: req.body.user_id
}, {
$set: {
prescription: [ { "doctor_id" : req.body.doctor_id, "prescription" : [
{
"medicine_id" : req.body.medicine_id
}]} ],
}
}, {
upsert: true
}, function(err) {
if (err) {
res.status(202).json({
"success": "0",
"message": err
})
} else {
res.status(200).json({
"success": "1",
"message": "Prescription given successfully"
});
}
})
I don't know how to check whether the doctor_id already exists and if it does not exists it should add a new array, and if it exists it should add inside the existing arrays
Take a look in this answer.
But basically you can use the $ operator which identifies an element in an array.
You can see here some mongodb array operators.