static

in grails-data-mongodb/core/src/main/groovy/org/grails/datastore/mapping/mongo/query/MongoQuery.java [112:351]


    static {
        queryHandlers.put(IdEquals.class, new QueryHandler<IdEquals>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, IdEquals criterion, Document query, PersistentEntity entity) {
                Object value = criterion.getValue();
                MappingContext mappingContext = entity.getMappingContext();
                PersistentProperty identity = entity.getIdentity();
                Object converted = mappingContext.getConversionService().convert(value, identity.getType());
                query.put(MongoEntityPersister.MONGO_ID_FIELD, converted);
            }
        });

        queryHandlers.put(AssociationQuery.class, new QueryHandler<AssociationQuery>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, AssociationQuery criterion, Document query, PersistentEntity entity) {
                Association<?> association = criterion.getAssociation();
                PersistentEntity associatedEntity = association.getAssociatedEntity();
                if (association instanceof EmbeddedCollection) {
                    Document associationCollectionQuery = new Document();
                    populateMongoQuery(queryEncoder, associationCollectionQuery, criterion.getCriteria(), associatedEntity);
                    Document collectionQuery = new Document("$elemMatch", associationCollectionQuery);
                    String propertyKey = getPropertyName(entity, association.getName());
                    query.put(propertyKey, collectionQuery);
                } else if (associatedEntity instanceof EmbeddedPersistentEntity || association instanceof Embedded) {
                    Document associatedEntityQuery = new Document();
                    populateMongoQuery(queryEncoder, associatedEntityQuery, criterion.getCriteria(), associatedEntity);
                    for (String property : associatedEntityQuery.keySet()) {
                        String propertyKey = getPropertyName(entity, association.getName());
                        query.put(propertyKey + '.' + property, associatedEntityQuery.get(property));
                    }
                } else {
                    throw new UnsupportedOperationException("Join queries are not supported by MongoDB");
                }
            }
        });





        queryHandlers.put(WithinBox.class, new QueryHandler<WithinBox>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, WithinBox withinBox, Document query, PersistentEntity entity) {
                Document nearQuery = new Document();
                Document box = new Document();
                MongoEntityPersister.setDBObjectValue(box, BOX_OPERATOR, withinBox.getValues(), entity.getMappingContext());
                nearQuery.put(WITHIN_OPERATOR, box);
                String propertyName = getPropertyName(entity, withinBox);
                query.put(propertyName, nearQuery);
            }
        });

        queryHandlers.put(WithinPolygon.class, new QueryHandler<WithinPolygon>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, WithinPolygon withinPolygon, Document query, PersistentEntity entity) {
                Document nearQuery = new Document();
                Document box = new Document();
                MongoEntityPersister.setDBObjectValue(box, POLYGON_OPERATOR, withinPolygon.getValues(), entity.getMappingContext());
                nearQuery.put(WITHIN_OPERATOR, box);
                String propertyName = getPropertyName(entity, withinPolygon);
                query.put(propertyName, nearQuery);
            }
        });

        queryHandlers.put(WithinCircle.class, new QueryHandler<WithinCircle>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, WithinCircle withinCentre, Document query, PersistentEntity entity) {
                Document nearQuery = new Document();
                Document center = new Document();
                MongoEntityPersister.setDBObjectValue(center, CENTER_OPERATOR, withinCentre.getValues(), entity.getMappingContext());
                nearQuery.put(WITHIN_OPERATOR, center);
                String propertyName = getPropertyName(entity, withinCentre);
                query.put(propertyName, nearQuery);
            }
        });

        QueryHandler<Near> nearHandler = new QueryHandler<Near>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, Near near, Document query, PersistentEntity entity) {
                Document nearQuery = new Document();
                Object value = near.getValue();
                String nearOperator = near instanceof NearSphere ? NEAR_SPHERE_OPERATOR : NEAR_OPERATOR;
                if ((value instanceof List) || (value instanceof Map)) {
                    MongoEntityPersister.setDBObjectValue(nearQuery, nearOperator, value, entity.getMappingContext());
                } else if (value instanceof Point) {
                    Document geoJson = GeoJSONType.convertToGeoDocument((Point) value);
                    Document geometry = new Document();
                    geometry.put(GEOMETRY_OPERATOR, geoJson);
                    if (near.maxDistance != null) {
                        geometry.put(MAX_DISTANCE_OPERATOR, near.maxDistance.getValue());
                    }
                    nearQuery.put(nearOperator, geometry);
                }

                String propertyName = getPropertyName(entity, near);
                query.put(propertyName, nearQuery);
            }
        };
        queryHandlers.put(Near.class, nearHandler);
        queryHandlers.put(NearSphere.class, nearHandler);

        queryHandlers.put(GeoWithin.class, new QueryHandler<GeoWithin>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, GeoWithin geoWithin, Document query, PersistentEntity entity) {
                Document queryRoot = new Document();
                Document queryGeoWithin = new Document();
                queryRoot.put(GEO_WITHIN_OPERATOR, queryGeoWithin);
                String targetProperty = getPropertyName(entity, geoWithin);
                Object value = geoWithin.getValue();
                if (value instanceof Shape) {
                    Shape shape = (Shape) value;
                    if (shape instanceof Polygon) {
                        Polygon p = (Polygon) shape;
                        Document geoJson = GeoJSONType.convertToGeoDocument(p);
                        queryGeoWithin.put(GEOMETRY_OPERATOR, geoJson);
                    } else if (shape instanceof Box) {
                        queryGeoWithin.put(BOX_OPERATOR, shape.asList());
                    } else if (shape instanceof Circle) {
                        queryGeoWithin.put(CENTER_OPERATOR, shape.asList());
                    } else if (shape instanceof Sphere) {
                        queryGeoWithin.put(CENTER_SPHERE_OPERATOR, shape.asList());
                    }
                } else if (value instanceof Map) {
                    queryGeoWithin.putAll((Map) value);
                }

                query.put(targetProperty, queryRoot);
            }
        });

        queryHandlers.put(GeoIntersects.class, new QueryHandler<GeoIntersects>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, GeoIntersects geoIntersects, Document query, PersistentEntity entity) {
                Document queryRoot = new Document();
                Document queryGeoWithin = new Document();
                queryRoot.put(GEO_INTERSECTS_OPERATOR, queryGeoWithin);
                String targetProperty = getPropertyName(entity, geoIntersects);
                Object value = geoIntersects.getValue();
                if (value instanceof GeoJSON) {
                    Shape shape = (Shape) value;
                    Document geoJson = GeoJSONType.convertToGeoDocument(shape);
                    queryGeoWithin.put(GEOMETRY_OPERATOR, geoJson);
                } else if (value instanceof Map) {
                    queryGeoWithin.putAll((Map) value);
                }

                query.put(targetProperty, queryRoot);
            }
        });
        queryHandlers.put(Conjunction.class, new QueryHandler<Conjunction>() {
            public void handle(EmbeddedQueryEncoder queryEncoder, Conjunction criterion, Document query, PersistentEntity entity) {
                populateMongoQuery(queryEncoder, query, criterion, entity);
            }
        });

        queryHandlers.put(Disjunction.class, new QueryHandler<Disjunction>() {
            @SuppressWarnings("unchecked")
            public void handle(EmbeddedQueryEncoder queryEncoder, Disjunction criterion, Document query, PersistentEntity entity) {
                populateMongoQuery(queryEncoder, query, criterion, entity);
            }
        });

        groupByProjectionHandlers.put(AvgProjection.class, new ProjectionHandler<AvgProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, AvgProjection projection) {
                return addProjectionToGroupBy(projectObject, groupBy, projection, AVERAGE_OPERATOR, "avg_");
            }
        });
        groupByProjectionHandlers.put(CountProjection.class, new ProjectionHandler<CountProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, CountProjection projection) {
                projectObject.put(MongoEntityPersister.MONGO_ID_FIELD, 1);
                String projectionKey = "count";
                groupBy.put(projectionKey, new Document(SUM_OPERATOR, 1));
                return projectionKey;
            }
        });
        groupByProjectionHandlers.put(CountDistinctProjection.class, new ProjectionHandler<CountDistinctProjection>() {
            @Override
            // equivalent of "select count (distinct fieldName) from someTable". Example:
            // db.someCollection.aggregate([{ $group: { _id: "$fieldName"}  },{ $group: { _id: 1, count: { $sum: 1 } } } ])
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, CountDistinctProjection projection) {
                projectObject.put(projection.getPropertyName(), 1);
                String property = projection.getPropertyName();
                String projectionValueKey = "countDistinct_" + property;
                Document id = getIdObjectForGroupBy(groupBy);
                id.put(projectionValueKey, "$" + property);
                return projectionValueKey;
            }
        });

        groupByProjectionHandlers.put(MinProjection.class, new ProjectionHandler<MinProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, MinProjection projection) {
                return addProjectionToGroupBy(projectObject, groupBy, projection, MIN_OPERATOR, "min_");
            }
        });
        groupByProjectionHandlers.put(MaxProjection.class, new ProjectionHandler<MaxProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, MaxProjection projection) {
                return addProjectionToGroupBy(projectObject, groupBy, projection, MAX_OPERATOR, "max_");
            }
        });
        groupByProjectionHandlers.put(SumProjection.class, new ProjectionHandler<SumProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, SumProjection projection) {
                return addProjectionToGroupBy(projectObject, groupBy, projection, SUM_OPERATOR, "sum_");
            }
        });

        projectProjectionHandlers.put(DistinctPropertyProjection.class, new ProjectionHandler<DistinctPropertyProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, DistinctPropertyProjection projection) {
                String property = projection.getPropertyName();
                projectObject.put(property, 1);
                Document id = getIdObjectForGroupBy(groupBy);
                String projectedValueKey = property.replace('.', '_');
                id.put(projectedValueKey, "$" + property);
                return projectedValueKey;
            }
        });

        projectProjectionHandlers.put(PropertyProjection.class, new ProjectionHandler<PropertyProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, PropertyProjection projection) {
                String property = projection.getPropertyName();
                projectObject.put(property, 1);
                Document id = getIdObjectForGroupBy(groupBy);
                String projectedValueKey = property.replace('.', '_');
                id.put(projectedValueKey, "$" + property);
                // we add the id to the grouping to make it not distinct
                id.put(MongoEntityPersister.MONGO_ID_FIELD, "$" + MongoEntityPersister.MONGO_ID_FIELD);
                return projectedValueKey;
            }
        });

        projectProjectionHandlers.put(IdProjection.class, new ProjectionHandler<IdProjection>() {
            @Override
            public String handle(PersistentEntity entity, Document projectObject, Document groupBy, IdProjection projection) {
                projectObject.put(MongoEntityPersister.MONGO_ID_FIELD, 1);
                Document id = getIdObjectForGroupBy(groupBy);
                id.put(MongoEntityPersister.MONGO_ID_FIELD, "$_id");

                return MongoEntityPersister.MONGO_ID_FIELD;
            }
        });

    }