Introduction(简介)
Query接口是个相当直接的方法。他允许非常确切的过滤方式(基于属性),排序,一个偏移和限制返回结果的数量。
query实现也实现了QueryResults接口,此接口允许在查询中访问结果。
Filter(过滤)
一般的.filter(criteria, value)语法被支持。标准语法是属性名和操作("field > ", or "field in")的整合。所有的语法被逻辑"and" 暗暗的联系在一起。
2 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ); |
3 |
Datastore ds = ... Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ); |
查询foo在12和30之间的实体对象,的方法如下:
3 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ).filter( "foo <" , 30 ); |
4 |
Datastore ds = ... Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ).filter( "foo <" , 30 ); |
Operators(操作符)
操作符被用在fileter(...)和MongoDB的查询操作紧密的匹配。
operator
|
mongo op |
= |
$eq |
!=, <> |
$ne |
>,<,>=,<= |
$gt,$lt,$gte,$lte |
in |
$in |
nin |
$nin |
elem |
$elemMatch |
exists |
$exists |
all |
$all |
size |
$size |
... |
... |
操作符被用在fileter(...)和MongoDB的查询操作紧密的匹配。
operator
|
mongo op |
= |
$eq |
!=, <> |
$ne |
>,<,>=,<= |
$gt,$lt,$gte,$lte |
in |
$in |
nin |
$nin |
elem |
$elemMatch |
exists |
$exists |
all |
$all |
size |
$size |
... |
... |
Fluent Interface
沿着.filter(...)方法,这里有个流水型的方法。这些提供一个非常已读的格式。
fluent 接口以field(name)开始。接着一下任何一个方法都可以添加到这个格式中,
-
1 |
Query q = ds.createQuery(MyEntity. class ).field( "foo" ).equal( 1 ); |
3 |
q.field( "bar" ).greaterThan( 12 ); |
4 |
q.field( "bar" ).lessThan( 40 ); |
Methods(方法)
method |
operation |
comment |
exists |
$exists |
|
doesNotExist |
$exists |
|
greaterThan,greatherThanOrEq,lessThan,lessThanOrEe |
$gt,$gte,$lt,$lte |
|
equal,notEqual |
$eq, $ne |
|
hasThisOne |
$eq |
|
hasAllOf |
$all |
|
hasAnyOf |
$in |
|
hasNoneOf |
$nin |
|
hasThisElement |
$elemMatch |
|
sizeEq |
$size |
|
Geo-spatial
所有的geo-spatial方法都被分解为"near, 和within"。所有的near查询将会产生结果,按远程和最近的结果。
下面的方法接受一个球形的最后参数,表名他们是否应该使用$sphere选项。
Method operation comment
near(x, y) |
$near |
|
near(x, y, r) |
$near |
(w/maxDistance of r) |
within(x, y, r) |
$within + $center |
|
within(x1, y1, x2, y2) |
$within + $box |
|
-
02 |
static private class Place { |
03 |
@Id protected ObjectId id; |
04 |
protected String name = "" ; |
05 |
@Indexed (IndexDirection.GEO2D) |
06 |
protected double [] loc = null ; |
08 |
public Place(String name, double [] loc) { |
15 |
Place place1 = new Place( "place1" , new double [] { 1 , 1 }); |
18 |
Place found = ds.find(Place. class ).field( "loc" ).near(, ).get(); |
Or
使用流式查询接口时你也可以像一下这样使用"or"查询
-
1 |
Query<Person> q = ad.createQuery(Person. class ); |
3 |
q.criteria( "firstName" ).equal( "scott" ), |
4 |
q.criteria( "lastName" ).equal( "scott" ) |
Fields
属性名也可以像在本地MongoDB查询中那样使用"."标识
-
1 |
Query q = ds.createQuery(Person. class ).field( "addresses.city" ).equal( "San Francisco" ); |
3 |
Query q = ds.find(Person. class , "addresses.city" , "San Francisco" ); |
Validation(验证)
验证被应用在属性名,和数据类型上。如果在查询中使用的属性名在指定的java类中没有找到将会抛出一个异常。如果一个属性名被“.”标识连接,那么这个表达式的每个
部分都将会在指定的java对象中进行验证(有一个异常Map来记录那个属性 名被跳过)。
数据类型问题(比较属性类型和参数类型)作为警告被记录,由于服务器可能会把数据强制转换,或者你发送意思不那么的有意义;服务器使用字节表示一些参数,所以有些类型
不同的数值也可以匹配(例如数字)。
Disabling validation(是验证无效)
通过调用disableValidation()可以使验证变为无效,在开始等于查询或每个查询语句上。
2 |
Query q = ds.createQuery(MyEntity. class ).disableValidation(); |
6 |
Query q = ds.createQuery(MyEntity. class ).disableValidation().filter( "someOldField" , value).enableValidation().filter( "realField" , otherVal); |
Sort(排序)
你可以通过一个或多个属性名对结果进行升序或降序排序
2 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ).order( "dateAdded" ); |
4 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ).order( "-dateAdded" ); |
6 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ).order( "dateAdded, -foo" ); |
Offset(skip)
你可以通过在查询是指定一个偏移值是服务器跳过一些记录元素。这将比使用几个属性的范围进行查询要低效的多。如下所示:
2 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ).offset( 1000 ); |
Ignoring Fields(忽略属性)
MongoDB也支持只返回一些属性。这在应用中显得有点奇怪,但是这个在修剪掉一部分嵌套时是非常有用的方法。这将会导致局部实体对象,应该不慎重使用,如果可以的话。
02 |
MyEntity e = ds.createQuery(MyEntity. class ).retrievedFields( true , "foo" ).get(); |
08 |
MyEntity e = ds.createQuery(MyEntity. class ).retrievedFields( false , "foo" ).get(); |
11 |
Datastore ds = ... MyEntity e = ds.createQuery(MyEntity. class ).retrievedFields( true , "foo" ).get(); val = e.getFoo(); |
Returning Data
(返回值)
仅仅访问QueryResults的一个方法就可以返回你的数据。没有一个方法会影响Query。他们将会单独的离开Query,因此你可以继续通过调用相应的方法来获取你想要的数据。
method does
get() |
返回第一个Entity,--使用limit(1) |
asList() |
以一个集合的方式返回所有的结果项, 如果一个大的数据结果将会付出代价 |
fetch() |
明确的返回一个Iterable实例 |
asKeyList() |
以List的方式返回所有数据项的Key<T> ---仅仅在服务器中得到ID属性 |
fetchEmptyEntities() |
仅仅想fetch()方法,但是使用id属性填充 |
02 |
Query q = ds.createQuery(MyEntity. class ).filter( "foo >" , 12 ); |
07 |
e = q.sort( "foo" ).get(); |
14 |
List<MyEntity> entities = q.asList() |