Skip to content

$near query not working (error in parsing) #201

Open
@ziedHamdi

Description

@ziedHamdi

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
												}
											}
										}
									}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions