Description
Hi,
I'm trying to execute a near query with the following filter :
{"category":null,"viewer":"USER","location":{"$near":{"$geometry":{"type":"Point","coordinates":[10.3222671,36.88911649999999]},"$maxDistance":50000}}}
But I get the following error:
graphQl error : Cannot read property 'forEach' of undefined
graphQl error stack: TypeError: Cannot read property 'forEach' of undefined
at castArraysOfNumbers (D:\Zied\work\weally\node_modules\mongoose\lib\schema\operators\helpers.js:25:7)
at cast$geometry (D:\Zied\work\weally\node_modules\mongoose\lib\schema\operators\geospatial.js:41:7)
at SingleNestedPath.cast$near (D:\Zied\work\weally\node_modules\mongoose\lib\schema\operators\geospatial.js:29:12)
at SingleNestedPath.castForQuery (D:\Zied\work\weally\node_modules\mongoose\lib\schema\SingleNestedPath.js:197:20)
at SingleNestedPath.SchemaType.castForQueryWrapper (D:\Zied\work\weally\node_modules\mongoose\lib\schematype.js:1326:17)
at cast (D:\Zied\work\weally\node_modules\mongoose\lib\cast.js:288:39)
at model.Query.Query.cast (D:\Zied\work\weally\node_modules\mongoose\lib\query.js:4607:12)
at model.Query.<anonymous> (D:\Zied\work\weally\node_modules\mongoose\lib\query.js:2183:10)
at model.Query._wrappedThunk [as _countDocuments] (D:\Zied\work\weally\node_modules\mongoose\lib\helpers\query\wrapThunk.js:16:8)
at process.nextTick (D:\Zied\work\weally\node_modules\kareem\index.js:369:33)
at process._tickCallback (internal/process/next_tick.js:61:11)
I logged the object you pass to cast$geometry :
function cast$geometry(val, self) {
console.log( "geospacial cast$geometry Value : ", val )
switch (val.$geometry.type) {
case 'Polygon':
case 'LineString':
case 'Point':
castArraysOfNumbers(val.$geometry.coordinates, self);
break;
default:
// ignore unknowns
break;
}
_castMinMaxDistance(self, val);
return val;
}
And that object is completely different from what you seam to expect (it is displayed twice):
geospacial cast$geometry Value : { '$geometry':
{ type: 'Point',
'coordinates.0': 10.3222671,
'coordinates.1': 36.88911649999999 },
'$maxDistance': 50000 }
geospacial cast$geometry Value : { '$geometry':
{ type: 'Point',
'coordinates.0': 10.3222671,
'coordinates.1': 36.88911649999999 },
'$maxDistance': 50000 }
I'm using the latest versions of the lib:
"graphql-compose": "^7.8.0",
"graphql-compose-mongoose": "^7.3.1",
I upgraded from gcmongoose 7.1.1 since I had another bug : the query was correctly interpreted and logged by mongoose but there was a missing argument when querying : (the find method was called with two arguments instead of three which caused other errors)
Just for easier testing, I provide below the code I use to get to this issue:
graph/complaint.js
const addComplaintByLocationSearch = function (resolverName) {
const extendedResolver = ComplaintTC.getResolver(resolverName).addFilterArg({
name: 'position',
type: InputLatLngTC,
description: 'Search around a given position (lat, lng) in priority',
query: (query, value, resolveParams) => {
// FIXME do localized query
// query.name = new RegExp(value, 'i');
},
});
extendedResolver.name = resolverName;
ComplaintTC.addResolver(extendedResolver);
}
function wrapFindResolver(resolverName) {
addComplaintByLocationSearch(resolverName)
const findResolver = ComplaintTC.getResolver(resolverName);
return findResolver.wrapResolve(next => async rp => {
const filter = rp.args.filter;
const entityId = filter.entityId;
const position = filter.position;
if (!entityId && position != null && position.lat != null) {
filter.location = {
$near: {
$geometry: {
type: "Point",
coordinates: [position.lng, position.lat]
},
$maxDistance: 50000
}
}
//saved as location in db
filter.position = undefined
console.log('########### args after : ', JSON.stringify( filter ) )
}
return next(rp)
})
db/complaint.js (irrelevant fields removed)
const ComplainSchema = new Schema({
entityGroupId: {type: String},
entityId: {type: String},
entity: {
name: {type: String},
kind: {type: String},
groupTree: [GroupTreeItem],
},
categoryName: {type: String},
orderId: String,
location: PointSchema,
})
db/point.js
import mongoose from "mongoose";
export const PointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point'],
required: true,
default:'Point'
},
coordinates: {
type: [Number],
required: false
}
});
The query I use is:
const COMPLAINTS = gql`
query complaintConnection( $kind: String, $position: LatLngInput, $categoryName: String, $after: String){
complaintConnection(after:$after, filter: { viewer: "USER", kind: $kind, category: $categoryName, position:$position }, first: 12, sort:POPULARITY_DESC) {
count
pageInfo {
startCursor,
endCursor,
hasNextPage,
hasPreviousPage
},
edges {
cursor,
node {
_id,
entityId,
stats {
COMMENT {
actionCount,
userCount
},
USER_LIKE {
userCount
},
SAME_ISSUE {
actionCount,
userCount,
USER_ACTION_EXPECTED,
USER_ACTION_REFUSED,
SHOP_ACTION_EXPECTED,
SHOP_ACTION_REFUSED,
USER_SATISFIED
},
},
entity {
name
},
user {
userId,
userName,
roleInShop
},
title,
desc,
video,
attachments {
url
},
mainAttachmentIndex,
state,
public,
interactionState,
interactionSpecifier,
unanswered,
createdAt,
updatedAt
}
}
}
}`