mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-27 21:01:15 +08:00
536 lines
18 KiB
Java
536 lines
18 KiB
Java
/*
|
|
* Copyright 2011, Mysema Ltd
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
package com.mysema.query.mongodb;
|
|
|
|
import static java.util.Arrays.asList;
|
|
import static junit.framework.Assert.assertEquals;
|
|
import static junit.framework.Assert.assertNotNull;
|
|
import static org.junit.Assert.assertFalse;
|
|
import static org.junit.Assert.assertNull;
|
|
import static org.junit.Assert.assertTrue;
|
|
|
|
import java.net.UnknownHostException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Date;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
|
|
import com.mysema.query.mongodb.domain.*;
|
|
import org.bson.types.ObjectId;
|
|
import org.junit.Before;
|
|
import org.junit.Test;
|
|
import org.junit.experimental.categories.Category;
|
|
import org.mongodb.morphia.Datastore;
|
|
import org.mongodb.morphia.Morphia;
|
|
|
|
import com.google.common.collect.Lists;
|
|
import com.mongodb.Mongo;
|
|
import com.mongodb.MongoException;
|
|
import com.mongodb.ReadPreference;
|
|
import com.mysema.query.NonUniqueResultException;
|
|
import com.mysema.query.SearchResults;
|
|
import com.mysema.query.mongodb.domain.QAddress;
|
|
import com.mysema.query.mongodb.domain.QItem;
|
|
import com.mysema.query.mongodb.domain.QMapEntity;
|
|
import com.mysema.query.mongodb.domain.QUser;
|
|
import com.mysema.query.mongodb.domain.User.Gender;
|
|
import com.mysema.query.mongodb.morphia.MorphiaQuery;
|
|
import com.mysema.query.types.EntityPath;
|
|
import com.mysema.query.types.OrderSpecifier;
|
|
import com.mysema.query.types.Predicate;
|
|
import com.mysema.query.types.path.StringPath;
|
|
import com.mysema.testutil.ExternalDB;
|
|
|
|
@Category(ExternalDB.class)
|
|
public class MongodbQueryTest {
|
|
|
|
private final Mongo mongo;
|
|
private final Morphia morphia;
|
|
private final Datastore ds;
|
|
|
|
private final String dbname = "testdb";
|
|
private final QUser user = QUser.user;
|
|
private final QItem item = QItem.item;
|
|
private final QAddress address = QAddress.address;
|
|
private final QMapEntity mapEntity = QMapEntity.mapEntity;
|
|
private final QDates dates = QDates.dates;
|
|
|
|
List<User> users = Lists.newArrayList();
|
|
User u1, u2, u3, u4;
|
|
City tampere, helsinki;
|
|
|
|
public MongodbQueryTest() throws UnknownHostException, MongoException {
|
|
mongo = new Mongo();
|
|
morphia = new Morphia().map(User.class).map(Item.class).map(MapEntity.class).map(Dates.class);
|
|
ds = morphia.createDatastore(mongo, dbname);
|
|
}
|
|
|
|
@Before
|
|
public void before() throws UnknownHostException, MongoException {
|
|
ds.delete(ds.createQuery(Item.class));
|
|
ds.delete(ds.createQuery(User.class));
|
|
ds.delete(ds.createQuery(MapEntity.class));
|
|
|
|
tampere = new City("Tampere", 61.30, 23.50);
|
|
helsinki= new City("Helsinki", 60.15, 20.03);
|
|
|
|
u1 = addUser("Jaakko", "Jantunen", 20, new Address("Aakatu", "00100", helsinki),
|
|
new Address("Aakatu1", "00100", helsinki),
|
|
new Address("Aakatu2", "00100", helsinki));
|
|
u2 = addUser("Jaakki", "Jantunen", 30, new Address("Beekatu", "00200", helsinki));
|
|
u3 = addUser("Jaana", "Aakkonen", 40, new Address("Ceekatu","00300", tampere));
|
|
u4 = addUser("Jaana", "BeekkoNen", 50, new Address("Deekatu","00400",tampere));
|
|
}
|
|
|
|
@Test
|
|
public void List_Keys() {
|
|
User u = where(user.firstName.eq("Jaakko")).list(user.firstName, user.mainAddress().street).get(0);
|
|
assertEquals("Jaakko", u.getFirstName());
|
|
assertNull(u.getLastName());
|
|
assertEquals("Aakatu", u.getMainAddress().street);
|
|
assertNull(u.getMainAddress().postCode);
|
|
}
|
|
|
|
@Test
|
|
public void SingleResult_Keys() {
|
|
User u = where(user.firstName.eq("Jaakko")).singleResult(user.firstName);
|
|
assertEquals("Jaakko", u.getFirstName());
|
|
assertNull(u.getLastName());
|
|
}
|
|
|
|
@Test
|
|
public void UniqueResult_Keys() {
|
|
User u = where(user.firstName.eq("Jaakko")).uniqueResult(user.firstName);
|
|
assertEquals("Jaakko", u.getFirstName());
|
|
assertNull(u.getLastName());
|
|
}
|
|
|
|
@Test
|
|
public void List_Deep_Keys() {
|
|
User u = where(user.firstName.eq("Jaakko")).singleResult(user.addresses.any().street);
|
|
for (Address a : u.getAddresses()) {
|
|
assertNotNull(a.street);
|
|
assertNull(a.city);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void Contains() {
|
|
assertQuery(user.friends.contains(u1), u3, u4, u2);
|
|
}
|
|
|
|
@Test
|
|
public void Contains2() {
|
|
assertQuery(user.friends.contains(u4));
|
|
}
|
|
|
|
@Test
|
|
public void NotContains() {
|
|
assertQuery(user.friends.contains(u1).not(), u1);
|
|
}
|
|
|
|
@Test
|
|
public void Contains_Key() {
|
|
MapEntity entity = new MapEntity();
|
|
entity.getProperties().put("key", "value");
|
|
ds.save(entity);
|
|
|
|
assertTrue(query(mapEntity).where(mapEntity.properties.get("key").isNotNull()).exists());
|
|
assertFalse(query(mapEntity).where(mapEntity.properties.get("key2").isNotNull()).exists());
|
|
|
|
assertTrue(query(mapEntity).where(mapEntity.properties.containsKey("key")).exists());
|
|
assertFalse(query(mapEntity).where(mapEntity.properties.containsKey("key2")).exists());
|
|
}
|
|
|
|
@Test
|
|
public void Equals_Ignore_Case() {
|
|
assertTrue(where(user.firstName.equalsIgnoreCase("jAaKko")).exists());
|
|
assertFalse(where(user.firstName.equalsIgnoreCase("AaKk")).exists());
|
|
}
|
|
|
|
@Test
|
|
public void Exists() {
|
|
assertTrue(where(user.firstName.eq("Jaakko")).exists());
|
|
assertFalse(where(user.firstName.eq("JaakkoX")).exists());
|
|
assertTrue(where(user.id.eq(u1.getId())).exists());
|
|
}
|
|
|
|
@Test
|
|
public void Find_By_Id() {
|
|
assertNotNull(where(user.id.eq(u1.getId())).singleResult() != null);
|
|
}
|
|
|
|
@Test
|
|
public void NotExists() {
|
|
assertFalse(where(user.firstName.eq("Jaakko")).notExists());
|
|
assertTrue(where(user.firstName.eq("JaakkoX")).notExists());
|
|
}
|
|
|
|
@Test
|
|
public void UniqueResult() {
|
|
assertEquals("Jantunen", where(user.firstName.eq("Jaakko")).uniqueResult().getLastName());
|
|
}
|
|
|
|
@Test(expected=NonUniqueResultException.class)
|
|
public void UniqueResultContract() {
|
|
where(user.firstName.isNotNull()).uniqueResult();
|
|
}
|
|
|
|
@Test
|
|
public void SingleResult() {
|
|
where(user.firstName.isNotNull()).singleResult();
|
|
}
|
|
|
|
@Test
|
|
public void LongPath() {
|
|
assertEquals(2, query().where(user.mainAddress().city().name.eq("Helsinki")).count());
|
|
assertEquals(2, query().where(user.mainAddress().city().name.eq("Tampere")).count());
|
|
}
|
|
|
|
@Test
|
|
public void CollectionPath() {
|
|
assertEquals(1, query().where(user.addresses.any().street.eq("Aakatu1")).count());
|
|
assertEquals(0, query().where(user.addresses.any().street.eq("akatu")).count());
|
|
}
|
|
|
|
@Test
|
|
public void Dates() {
|
|
Date start = new Date();
|
|
ds.delete(ds.createQuery(Dates.class));
|
|
Dates d = new Dates();
|
|
d.setDate(new Date());
|
|
ds.save(d);
|
|
Date end = new Date();
|
|
|
|
assertEquals(d, query(dates).where(dates.date.between(start, end)).singleResult());
|
|
}
|
|
|
|
@Test
|
|
public void ElemMatch() {
|
|
// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1"}}}
|
|
assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1")).count());
|
|
// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1" , "postCode" : "00100"}}}
|
|
assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1"), address.postCode.eq("00100")).count());
|
|
// { "addresses" : { "$elemMatch" : { "street" : "akatu"}}}
|
|
assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("akatu")).count());
|
|
// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1" , "postCode" : "00200"}}}
|
|
assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1"), address.postCode.eq("00200")).count());
|
|
}
|
|
|
|
@Test
|
|
public void IndexedAccess() {
|
|
assertEquals(1, query().where(user.addresses.get(0).street.eq("Aakatu1")).count());
|
|
assertEquals(0, query().where(user.addresses.get(1).street.eq("Aakatu1")).count());
|
|
}
|
|
|
|
@Test
|
|
public void Count() {
|
|
assertEquals(4, query().count());
|
|
}
|
|
|
|
@Test
|
|
public void Order() {
|
|
List<User> users = query().orderBy(user.age.asc()).list();
|
|
assertEquals(asList(u1, u2, u3, u4), users);
|
|
|
|
users = query().orderBy(user.age.desc()).list();
|
|
assertEquals(asList(u4, u3, u2, u1), users);
|
|
}
|
|
|
|
@Test
|
|
public void Restrict() {
|
|
assertEquals(asList(u1, u2), query().limit(2).orderBy(user.age.asc()).list());
|
|
assertEquals(asList(u2, u3), query().limit(2).offset(1).orderBy(user.age.asc()).list());
|
|
}
|
|
|
|
@Test
|
|
public void ListResults() {
|
|
SearchResults<User> results = query().limit(2).orderBy(user.age.asc()).listResults();
|
|
assertEquals(4l, results.getTotal());
|
|
assertEquals(2, results.getResults().size());
|
|
|
|
results = query().offset(2).orderBy(user.age.asc()).listResults();
|
|
assertEquals(4l, results.getTotal());
|
|
assertEquals(2, results.getResults().size());
|
|
}
|
|
|
|
@Test
|
|
public void EmptyResults() {
|
|
SearchResults<User> results = query().where(user.firstName.eq("XXX")).listResults();
|
|
assertEquals(0l, results.getTotal());
|
|
assertEquals(Collections.emptyList(), results.getResults());
|
|
}
|
|
|
|
@Test
|
|
public void EqInAndOrderByQueries() {
|
|
assertQuery(user.firstName.eq("Jaakko"), u1);
|
|
assertQuery(user.firstName.equalsIgnoreCase("jaakko"), u1);
|
|
assertQuery(user.lastName.eq("Aakkonen"), u3);
|
|
|
|
assertQuery(user.firstName.in("Jaakko","Teppo"), u1);
|
|
assertQuery(user.lastName.in("Aakkonen","BeekkoNen"), u3, u4);
|
|
|
|
assertQuery(user.firstName.eq("Jouko"));
|
|
|
|
assertQuery(user.firstName.eq("Jaana"), user.lastName.asc(), u3, u4);
|
|
assertQuery(user.firstName.eq("Jaana"), user.lastName.desc(), u4, u3);
|
|
assertQuery(user.lastName.eq("Jantunen"), user.firstName.asc(), u2, u1);
|
|
assertQuery(user.lastName.eq("Jantunen"), user.firstName.desc(), u1, u2);
|
|
|
|
assertQuery(user.firstName.eq("Jaana").and(user.lastName.eq("Aakkonen")), u3);
|
|
//This shoud produce 'and' also
|
|
assertQuery(where(user.firstName.eq("Jaana"), user.lastName.eq("Aakkonen")), u3);
|
|
|
|
assertQuery(user.firstName.ne("Jaana"), u2, u1);
|
|
|
|
}
|
|
|
|
@Test
|
|
public void RegexQueries() {
|
|
assertQuery(user.firstName.startsWith("Jaan"), u3, u4);
|
|
assertQuery(user.firstName.startsWith("jaan"));
|
|
assertQuery(user.firstName.startsWithIgnoreCase("jaan"), u3, u4);
|
|
|
|
assertQuery(user.lastName.endsWith("unen"), u2, u1);
|
|
|
|
assertQuery(user.lastName.endsWithIgnoreCase("onen"), u3, u4);
|
|
|
|
assertQuery(user.lastName.contains("oN"), u4);
|
|
assertQuery(user.lastName.containsIgnoreCase("on"), u3, u4);
|
|
|
|
assertQuery(user.firstName.matches(".*aa.*[^i]$"), u3, u4, u1);
|
|
}
|
|
|
|
@Test
|
|
public void Like() {
|
|
assertQuery(user.firstName.like("Jaan"));
|
|
assertQuery(user.firstName.like("Jaan%"), u3, u4);
|
|
assertQuery(user.firstName.like("jaan%"));
|
|
|
|
assertQuery(user.lastName.like("%unen"), u2, u1);
|
|
}
|
|
|
|
@Test
|
|
public void IsNotNull() {
|
|
assertQuery(user.firstName.isNotNull(), u3, u4, u2, u1);
|
|
}
|
|
|
|
@Test
|
|
public void IsNull() {
|
|
assertQuery(user.firstName.isNull());
|
|
}
|
|
|
|
@Test
|
|
public void IsEmpty() {
|
|
assertQuery(user.firstName.isEmpty());
|
|
}
|
|
|
|
@Test
|
|
public void isEmpty2() {
|
|
assertQuery(user.friends.isEmpty(), u1);
|
|
}
|
|
|
|
@Test
|
|
public void Not() {
|
|
assertQuery(user.firstName.eq("Jaakko").not(), u3, u4, u2);
|
|
assertQuery(user.firstName.ne("Jaakko").not(), u1);
|
|
assertQuery(user.firstName.matches("Jaakko").not(), u3, u4, u2);
|
|
}
|
|
|
|
@Test
|
|
public void Or() {
|
|
assertQuery(user.lastName.eq("Aakkonen").or(user.lastName.eq("BeekkoNen")), u3, u4);
|
|
}
|
|
|
|
//This is not supported yet
|
|
// @Test
|
|
// public void UniqueResult() {
|
|
//
|
|
// addUser("Dille", "Duplikaatti");
|
|
// addUser("Dille", "Duplikaatti");
|
|
//
|
|
// assertEquals(2, where(user.firstName.eq("Dille")).count());
|
|
// assertEquals(1, where(user.firstName.eq("Dille")).countDistinct());
|
|
//
|
|
// }
|
|
|
|
@Test
|
|
public void Iterate() {
|
|
User a = addUser("A", "A");
|
|
User b = addUser("A1", "B");
|
|
User c = addUser("A2", "C");
|
|
|
|
Iterator<User> i = where(user.firstName.startsWith("A"))
|
|
.orderBy(user.firstName.asc())
|
|
.iterate();
|
|
|
|
assertEquals(a, i.next());
|
|
assertEquals(b, i.next());
|
|
assertEquals(c, i.next());
|
|
assertEquals(false, i.hasNext());
|
|
}
|
|
|
|
@Test
|
|
public void UniqueResultAndLimitAndOffset() {
|
|
MongodbQuery<User> q = query().where(user.firstName.startsWith("Ja")).orderBy(user.age.asc());
|
|
assertEquals(4, q.list().size());
|
|
assertEquals(u1, q.list().get(0));
|
|
}
|
|
|
|
@Test
|
|
public void Various() {
|
|
StringPath str = user.lastName;
|
|
List<Predicate> predicates = new ArrayList<Predicate>();
|
|
predicates.add(str.between("a", "b"));
|
|
predicates.add(str.contains("a"));
|
|
predicates.add(str.containsIgnoreCase("a"));
|
|
predicates.add(str.endsWith("a"));
|
|
predicates.add(str.endsWithIgnoreCase("a"));
|
|
predicates.add(str.eq("a"));
|
|
predicates.add(str.equalsIgnoreCase("a"));
|
|
predicates.add(str.goe("a"));
|
|
predicates.add(str.gt("a"));
|
|
predicates.add(str.in("a","b","c"));
|
|
predicates.add(str.isEmpty());
|
|
predicates.add(str.isNotNull());
|
|
predicates.add(str.isNull());
|
|
// predicates.add(str.like("a"));
|
|
predicates.add(str.loe("a"));
|
|
predicates.add(str.lt("a"));
|
|
predicates.add(str.matches("a"));
|
|
predicates.add(str.ne("a"));
|
|
predicates.add(str.notBetween("a", "b"));
|
|
predicates.add(str.notIn("a","b","c"));
|
|
predicates.add(str.startsWith("a"));
|
|
predicates.add(str.startsWithIgnoreCase("a"));
|
|
|
|
for (Predicate predicate : predicates) {
|
|
where(predicate).count();
|
|
where(predicate.not()).count();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void Enum_Eq() {
|
|
assertQuery(user.gender.eq(Gender.MALE), u3, u4, u2, u1);
|
|
}
|
|
|
|
@Test
|
|
public void Enum_Ne() {
|
|
assertQuery(user.gender.ne(Gender.MALE));
|
|
}
|
|
|
|
@Test
|
|
public void In_ObjectIds() {
|
|
Item i = new Item();
|
|
i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get()));
|
|
ds.save(i);
|
|
|
|
assertTrue(where(item, item.ctds.contains(i.getCtds().get(0))).count() > 0);
|
|
assertTrue(where(item, item.ctds.contains(ObjectId.get())).count() == 0);
|
|
}
|
|
|
|
@Test
|
|
public void In_ObjectIds2() {
|
|
Item i = new Item();
|
|
i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get()));
|
|
ds.save(i);
|
|
|
|
assertTrue(where(item, item.ctds.any().in(i.getCtds())).count() > 0);
|
|
assertTrue(where(item, item.ctds.any().in(Arrays.asList(ObjectId.get(), ObjectId.get()))).count() == 0);
|
|
}
|
|
|
|
@Test
|
|
public void Size() {
|
|
assertQuery(user.addresses.size().eq(2), u1);
|
|
}
|
|
|
|
@Test
|
|
public void ReadPreference() {
|
|
MorphiaQuery<User> query = query();
|
|
query.setReadPreference(ReadPreference.primary());
|
|
assertEquals(4, query.count());
|
|
|
|
}
|
|
|
|
//TODO
|
|
// - test dates
|
|
// - test with empty values and nulls
|
|
// - test more complex ands
|
|
|
|
private void assertQuery(Predicate e, User ... expected) {
|
|
assertQuery(where(e).orderBy(user.lastName.asc(), user.firstName.asc()), expected );
|
|
}
|
|
|
|
private void assertQuery(Predicate e, OrderSpecifier<?> orderBy, User ... expected ) {
|
|
assertQuery(where(e).orderBy(orderBy), expected);
|
|
}
|
|
|
|
private <T> MongodbQuery<T> where(EntityPath<T> entity, Predicate... e) {
|
|
return new MorphiaQuery<T>(morphia, ds, entity).where(e);
|
|
}
|
|
|
|
private MongodbQuery<User> where(Predicate ... e) {
|
|
return query().where(e);
|
|
}
|
|
|
|
private MorphiaQuery<User> query() {
|
|
return new MorphiaQuery<User>(morphia, ds, user);
|
|
}
|
|
|
|
private <T> MorphiaQuery<T> query(EntityPath<T> path) {
|
|
return new MorphiaQuery<T>(morphia, ds, path);
|
|
}
|
|
|
|
private void assertQuery(MongodbQuery<User> query, User ... expected ) {
|
|
//System.out.println(query.toString());
|
|
List<User> results = query.list();
|
|
|
|
assertNotNull(results);
|
|
if (expected == null ) {
|
|
assertEquals("Should get empty result", 0, results.size());
|
|
return;
|
|
}
|
|
assertEquals(expected.length, results.size());
|
|
int i = 0;
|
|
for (User u : expected) {
|
|
assertEquals(u, results.get(i++));
|
|
}
|
|
}
|
|
|
|
private User addUser(String first, String last) {
|
|
User user = new User(first, last);
|
|
ds.save(user);
|
|
return user;
|
|
}
|
|
|
|
private User addUser(String first, String last, int age, Address mainAddress, Address... addresses) {
|
|
User user = new User(first, last, age, new Date());
|
|
user.setGender(Gender.MALE);
|
|
user.setMainAddress(mainAddress);
|
|
for (Address address : addresses) {
|
|
user.addAddress(address);
|
|
}
|
|
for (User u : users) {
|
|
user.addFriend(u);
|
|
}
|
|
ds.save(user);
|
|
users.add(user);
|
|
return user;
|
|
}
|
|
|
|
}
|