Skip to content

Commit

Permalink
CSHARP-683: added query builder support for GeoJson queries.
Browse files Browse the repository at this point in the history
  • Loading branch information
craiggwilson committed Mar 8, 2013
1 parent ed1ca15 commit 48326fb
Show file tree
Hide file tree
Showing 3 changed files with 418 additions and 0 deletions.
306 changes: 306 additions & 0 deletions MongoDB.Driver/Builders/QueryBuilder.cs
Expand Up @@ -18,6 +18,7 @@
using System.Linq;
using System.Linq.Expressions;
using MongoDB.Bson;
using MongoDB.Driver.GeoJsonObjectModel;
using MongoDB.Driver.Linq;
using MongoDB.Driver.Linq.Utils;

Expand Down Expand Up @@ -157,6 +158,31 @@ public static IMongoQuery Exists(string name)
return new QueryDocument(name, new BsonDocument("$exists", true));
}

/// <summary>
/// Tests that a location element specified by name intersects with the geometry (see $geoIntersects).
/// </summary>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="name">The name.</param>
/// <param name="geometry">The geometry.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery GeoIntersects<TCoordinates>(string name, GeoJsonGeometry<TCoordinates> geometry)
where TCoordinates : GeoJsonCoordinates
{
if (name == null)
{
throw new ArgumentNullException("name");
}
if (geometry == null)
{
throw new ArgumentNullException("geometry");
}

var geoDoc = new BsonDocument("$geometry", BsonDocumentWrapper.Create(geometry));
var condition = new BsonDocument("$geoIntersects", geoDoc);

return new QueryDocument(name, condition);
}

/// <summary>
/// Tests that the value of the named element is greater than some value (see $gt).
/// </summary>
Expand Down Expand Up @@ -304,6 +330,65 @@ public static IMongoQuery Mod(string name, long modulus, long value)
return new QueryDocument(name, condition);
}

/// <summary>
/// Tests that the value of the named element is near a point (see $near).
/// </summary>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="name">The name of the element to test.</param>
/// <param name="point">The point.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Near<TCoordinates>(string name, GeoJsonPoint<TCoordinates> point)
where TCoordinates : GeoJsonCoordinates
{
return Near(name, point, double.MaxValue);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
/// <param name="name">The name of the element to test.</param>
/// <param name="x">The x value of the origin.</param>
/// <param name="y">The y value of the origin.</param>
/// <param name="maxDistance">The max distance.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Near<TCoordinates>(string name, GeoJsonPoint<TCoordinates> point, double maxDistance)
where TCoordinates : GeoJsonCoordinates
{
return Near(name, point, maxDistance, false);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
/// <param name="name">The name of the element to test.</param>
/// <param name="x">The x value of the origin.</param>
/// <param name="y">The y value of the origin.</param>
/// <param name="maxDistance">The max distance.</param>
/// <param name="spherical">if set to <c>true</c> then the query will be translated to $nearSphere.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Near<TCoordinates>(string name, GeoJsonPoint<TCoordinates> point, double maxDistance, bool spherical)
where TCoordinates : GeoJsonCoordinates
{
if (name == null)
{
throw new ArgumentNullException("name");
}
if (point == null)
{
throw new ArgumentNullException("point");
}

var geoDoc = new BsonDocument("$geometry", BsonDocumentWrapper.Create(point));
var op = spherical ? "$nearSphere" : "$near";
var condition = new BsonDocument(op, geoDoc);
if (maxDistance != double.MaxValue)
{
condition.Add("$maxDistance", maxDistance);
}

return new QueryDocument(name, condition);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
Expand Down Expand Up @@ -606,6 +691,31 @@ public static IMongoQuery Where(BsonJavaScript javascript)
return new QueryDocument("$where", javascript);
}

/// <summary>
/// Tests that the value of the named element is within the specified geometry (see $within).
/// </summary>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="name">The name of the element to test.</param>
/// <param name="geometry">The geometry.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Within<TCoordinates>(string name, GeoJsonGeometry<TCoordinates> geometry)
where TCoordinates : GeoJsonCoordinates
{
if (name == null)
{
throw new ArgumentNullException("name");
}
if (geometry == null)
{
throw new ArgumentNullException("geometry");
}

var geoDoc = new BsonDocument("$geometry", BsonDocumentWrapper.Create(geometry));
var condition = new BsonDocument("$within", geoDoc);

return new QueryDocument(name, condition);
}

/// <summary>
/// Tests that the value of the named element is within a circle (see $within and $center).
/// </summary>
Expand Down Expand Up @@ -831,6 +941,20 @@ public static IMongoQuery Exists<TMember>(Expression<Func<TDocument, TMember>> m
return new QueryBuilder<TDocument>().Exists(memberExpression);
}

/// <summary>
/// Tests that a location element specified by name intersects with the geometry (see $geoIntersects).
/// </summary>
/// <typeparam name="TMember">The type of the member.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="geometry">The geometry.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery GeoIntersects<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonGeometry<TCoordinates> geometry)
where TCoordinates : GeoJsonCoordinates
{
return new QueryBuilder<TDocument>().GeoIntersects(memberExpression, geometry);
}

/// <summary>
/// Tests that the value of the named element is greater than some value (see $gt).
/// </summary>
Expand Down Expand Up @@ -997,6 +1121,51 @@ public static IMongoQuery Mod(Expression<Func<TDocument, IEnumerable<int>>> memb
return new QueryBuilder<TDocument>().Mod(memberExpression, modulus, value);
}

/// <summary>
/// Tests that the value of the named element is near a point (see $near).
/// </summary>
/// <typeparam name="TMember">The type of the member.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="point">The point.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Near<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonPoint<TCoordinates> point)
where TCoordinates : GeoJsonCoordinates
{
return new QueryBuilder<TDocument>().Near(memberExpression, point);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
/// <typeparam name="TMember">The member type.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression representing the element to test.</param>
/// <param name="point">The point.</param>
/// <param name="maxDistance">The max distance.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Near<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonPoint<TCoordinates> point, double maxDistance)
where TCoordinates : GeoJsonCoordinates
{
return new QueryBuilder<TDocument>().Near(memberExpression, point, maxDistance);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
/// <typeparam name="TMember">The member type.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression representing the element to test.</param>
/// <param name="point">The point.</param>
/// <param name="maxDistance">The max distance.</param>
/// <param name="spherical">if set to <c>true</c> [spherical].</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Near<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonPoint<TCoordinates> point, double maxDistance, bool spherical)
where TCoordinates : GeoJsonCoordinates
{
return new QueryBuilder<TDocument>().Near(memberExpression, point, maxDistance, spherical);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
Expand Down Expand Up @@ -1144,6 +1313,20 @@ public static IMongoQuery Where(Expression<Func<TDocument, bool>> expression)
return new QueryBuilder<TDocument>().Where(expression);
}

/// <summary>
/// Tests that the value of the named element is within the specified geometry (see $within).
/// </summary>
/// <typeparam name="TMember">The type of the member.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="geometry">The geometry.</param>
/// <returns>An IMongoQuery.</returns>
public static IMongoQuery Within<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonGeometry<TCoordinates> geometry)
where TCoordinates : GeoJsonCoordinates
{
return new QueryBuilder<TDocument>().Within(memberExpression, geometry);
}

/// <summary>
/// Tests that the value of the named element is within a circle (see $within and $center).
/// </summary>
Expand Down Expand Up @@ -1356,6 +1539,30 @@ public IMongoQuery Exists<TMember>(Expression<Func<TDocument, TMember>> memberEx
return Query.Exists(serializationInfo.ElementName);
}

/// <summary>
/// Tests that a location element specified by name intersects with the geometry (see $geoIntersects).
/// </summary>
/// <typeparam name="TMember">The type of the member.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="geometry">The geometry.</param>
/// <returns>An IMongoQuery.</returns>
public IMongoQuery GeoIntersects<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonGeometry<TCoordinates> geometry)
where TCoordinates : GeoJsonCoordinates
{
if (memberExpression == null)
{
throw new ArgumentNullException("name");
}
if (geometry == null)
{
throw new ArgumentNullException("geometry");
}

var serializationInfo = _serializationInfoHelper.GetSerializationInfo(memberExpression);
return Query.GeoIntersects<TCoordinates>(serializationInfo.ElementName, geometry);
}

/// <summary>
/// Tests that the value of the named element is greater than some value (see $gt).
/// </summary>
Expand Down Expand Up @@ -1641,6 +1848,81 @@ public IMongoQuery Mod(Expression<Func<TDocument, IEnumerable<int>>> memberExpre
return Query.Mod(serializationInfo.ElementName, modulus, value);
}

/// <summary>
/// Tests that the value of the named element is near a point (see $near).
/// </summary>
/// <typeparam name="TMember">The type of the member.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="point">The point.</param>
/// <returns>An IMongoQuery.</returns>
public IMongoQuery Near<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonPoint<TCoordinates> point)
where TCoordinates : GeoJsonCoordinates
{
if (memberExpression == null)
{
throw new ArgumentNullException("memberExpression");
}
if (point == null)
{
throw new ArgumentNullException("point");
}

var serializationInfo = _serializationInfoHelper.GetSerializationInfo(memberExpression);
return Query.Near(serializationInfo.ElementName, point);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
/// <typeparam name="TMember">The member type.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="point">The point.</param>
/// <param name="maxDistance">The max distance.</param>
/// <returns>An IMongoQuery.</returns>
public IMongoQuery Near<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonPoint<TCoordinates> point, double maxDistance)
where TCoordinates : GeoJsonCoordinates
{
if (memberExpression == null)
{
throw new ArgumentNullException("memberExpression");
}
if (point == null)
{
throw new ArgumentNullException("point");
}

var serializationInfo = _serializationInfoHelper.GetSerializationInfo(memberExpression);
return Query.Near(serializationInfo.ElementName, point, maxDistance);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
/// <typeparam name="TMember">The member type.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="point">The point.</param>
/// <param name="maxDistance">The max distance.</param>
/// <param name="spherical">if set to <c>true</c> then the query will be translated to $nearSphere.</param>
/// <returns>An IMongoQuery.</returns>
public IMongoQuery Near<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonPoint<TCoordinates> point, double maxDistance, bool spherical)
where TCoordinates : GeoJsonCoordinates
{
if (memberExpression == null)
{
throw new ArgumentNullException("memberExpression");
}
if (point == null)
{
throw new ArgumentNullException("point");
}

var serializationInfo = _serializationInfoHelper.GetSerializationInfo(memberExpression);
return Query.Near(serializationInfo.ElementName, point, maxDistance, spherical);
}

/// <summary>
/// Tests that the value of the named element is near some location (see $near).
/// </summary>
Expand Down Expand Up @@ -1896,6 +2178,30 @@ public IMongoQuery Where(Expression<Func<TDocument, bool>> expression)
return _predicateTranslator.BuildQuery(evaluatedExpression);
}

/// <summary>
/// Tests that the value of the named element is within the specified geometry (see $within).
/// </summary>
/// <typeparam name="TMember">The type of the member.</typeparam>
/// <typeparam name="TCoordinates">The type of the coordinates.</typeparam>
/// <param name="memberExpression">The member expression.</param>
/// <param name="geometry">The geometry.</param>
/// <returns>An IMongoQuery.</returns>
public IMongoQuery Within<TMember, TCoordinates>(Expression<Func<TDocument, TMember>> memberExpression, GeoJsonGeometry<TCoordinates> geometry)
where TCoordinates : GeoJsonCoordinates
{
if (memberExpression == null)
{
throw new ArgumentNullException("memberExpression");
}
if (geometry == null)
{
throw new ArgumentNullException("geometry");
}

var serializationInfo = _serializationInfoHelper.GetSerializationInfo(memberExpression);
return Query.Within(serializationInfo.ElementName, geometry);
}

/// <summary>
/// Tests that the value of the named element is within a circle (see $within and $center).
/// </summary>
Expand Down

0 comments on commit 48326fb

Please sign in to comment.