Package org.mongodb.morphia

Source Code of org.mongodb.morphia.TestQuery$Keyword

/**
* Copyright (C) 2010 Olafur Gauti Gudmundsson
*
* 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 org.mongodb.morphia;


import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.MongoInternalException;
import org.bson.types.CodeWScope;
import org.bson.types.ObjectId;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.mongodb.morphia.TestDatastore.FacebookUser;
import org.mongodb.morphia.TestDatastore.KeysKeysKeys;
import org.mongodb.morphia.TestMapper.CustomId;
import org.mongodb.morphia.TestMapper.UsesCustomIdObject;
import org.mongodb.morphia.annotations.Embedded;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.annotations.Indexed;
import org.mongodb.morphia.annotations.Property;
import org.mongodb.morphia.annotations.Reference;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.QueryImpl;
import org.mongodb.morphia.query.ValidationException;
import org.mongodb.morphia.testmodel.Hotel;
import org.mongodb.morphia.testmodel.Rectangle;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mongodb.morphia.testutil.JSONMatcher.jsonEqual;


/**
* @author Scott Hernandez
*/
public class TestQuery extends TestBase {

    @Entity
    public static class Photo {
        @Id
        private ObjectId id;
        private List<String> keywords = Collections.singletonList("amazing");
    }


    public static class PhotoWithKeywords {
        @Id
        private ObjectId id;
        @Embedded
        private List<Keyword> keywords = Arrays.asList(new Keyword("california"), new Keyword("nevada"), new Keyword("arizona"));

        public PhotoWithKeywords() {
        }

        public PhotoWithKeywords(final String... words) {
            keywords = new ArrayList<Keyword>((int) (words.length));
            for (final String word : words) {
                keywords.add(new Keyword(word));
            }
        }
    }

    @Embedded(concreteClass = Keyword.class)
    public static class Keyword {
        private String keyword;
        private int score = 12;

        protected Keyword() {
        }

        public Keyword(final String k) {
            keyword = k;
        }
    }

    public static class ContainsPhotoKey {
        @Id
        private ObjectId id;
        private Key<Photo> photo;
    }

    @Entity
    public static class HasIntId {
        @Id
        private int id;

        protected HasIntId() {
        }

        HasIntId(final int id) {
            this.id = id;
        }
    }

    @Entity
    public static class ContainsPic {
        @Id
        private ObjectId id;
        private String name = "test";
        @Reference
        private Pic pic;
        @Reference(lazy = true)
        private Pic lazyPic;

        public ObjectId getId() {
            return id;
        }

        public void setId(final ObjectId id) {
            this.id = id;
        }

        public Pic getLazyPic() {
            return lazyPic;
        }

        public void setLazyPic(final Pic lazyPic) {
            this.lazyPic = lazyPic;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public Pic getPic() {
            return pic;
        }

        public void setPic(final Pic pic) {
            this.pic = pic;
        }
    }

    @Entity
    public static class Pic {
        @Id
        private ObjectId id;
        private String name;

        public Pic() {
        }

        public Pic(final String name) {
            this.name = name;
        }

        public ObjectId getId() {
            return id;
        }

        public void setId(final ObjectId id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }
    }

    public static class ContainsRenamedFields {
        @Id
        private ObjectId id;
        @Property("first_name")
        private String firstName = "Scott";
        @Property("last_name")
        private String lastName = "Hernandez";

        public ContainsRenamedFields() {
        }

        public ContainsRenamedFields(final String firstName, final String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }

    @Entity
    static class KeyValue {
        @Id
        private ObjectId id;
        /**
         * The list of keys for this value.
         */
        @Indexed(unique = true)
        private List<Object> key;
        /**
         * The id of the value document
         */
        @Indexed
        private ObjectId value;
    }

    @Entity
    static class GenericKeyValue<T> {

        @Id
        private ObjectId id;

        @Indexed(unique = true)
        private List<Object> key;

        @Embedded
        private T value;
    }

    @Entity
    static class ReferenceKeyValue {
        @Id
        private ReferenceKey id;
        /**
         * The list of keys for this value.
         */
        @Indexed(unique = true)
        @Reference
        private List<Pic> key;
        /**
         * The id of the value document
         */
        @Indexed
        private ObjectId value;
    }

    static class ReferenceKey {
        @Id
        private ObjectId id;
        private String name;

        ReferenceKey() {
        }

        ReferenceKey(final String name) {
            this.name = name;
        }

        @Override
        public boolean equals(final Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            final ReferenceKey that = (ReferenceKey) o;

            if (id != null ? !id.equals(that.id) : that.id != null) {
                return false;
            }
            if (name != null ? !name.equals(that.name) : that.name != null) {
                return false;
            }

            return true;
        }

        @Override
        public int hashCode() {
            int result = id != null ? id.hashCode() : 0;
            result = 31 * result + (name != null ? name.hashCode() : 0);
            return result;
        }
    }

    @Test
    public void testRenamedFieldQuery() throws Exception {
        getDs().save(new ContainsRenamedFields());

        assertNotNull(getDs().find(ContainsRenamedFields.class).field("firstName").equal("Scott").get());

        assertNotNull(getDs().find(ContainsRenamedFields.class).field("first_name").equal("Scott").get());
       
/*
        ContainsRenamedFields entity;

        entity = getDs().find(ContainsRenamedFields.class)
                     .field("first_name").equal("Scott")
                     .retrievedFields(true, "first_name")
                     .get();
        assertNull(entity.lastName);

        entity = getDs().find(ContainsRenamedFields.class)
                                           .field("first_name").equal("Scott")
                                           .retrievedFields(true, "firstName")
                                           .get();
        assertNull(entity.lastName);
       
*/
    }

    @Test
    public void testStartsWithQuery() throws Exception {
        getDs().save(new Photo());
        Photo p = getDs().find(Photo.class).field("keywords").startsWith("amaz").get();
        assertNotNull(p);
        p = getDs().find(Photo.class).field("keywords").startsWith("notareal").get();
        assertNull(p);

    }

    @Test
    public void testReferenceQuery() throws Exception {
        final Photo p = new Photo();
        final ContainsPhotoKey cpk = new ContainsPhotoKey();
        cpk.photo = getDs().save(p);
        getDs().save(cpk);

        assertNotNull(getDs().find(ContainsPhotoKey.class, "photo", p).get());
        assertNotNull(getDs().find(ContainsPhotoKey.class, "photo", cpk.photo).get());
        assertNull(getDs().find(ContainsPhotoKey.class, "photo", 1).get());

        try {
            getDs().find(ContainsPhotoKey.class, "photo.keywords", "foo").get();
            assertNull("um, query validation should have thrown");
        } catch (ValidationException e) {
            assertTrue(e.getMessage().contains("could not be found"));
        }
    }

    @Test
    public void testQueryOverReference() throws Exception {

        final ContainsPic cpk = new ContainsPic();
        final Pic p = new Pic();
        getDs().save(p);
        cpk.pic = p;

        getDs().save(cpk);

        final Query<ContainsPic> query = getDs().createQuery(ContainsPic.class);

        assertEquals(1, query.field("pic").equal(p).asList().size());

        try {
            getDs().find(ContainsPic.class, "pic.name", "foo").get();
            assertNull("um, query validation should have thrown");
        } catch (ValidationException e) {
            assertTrue(e.getMessage().contains("Can not use dot-"));
        }
    }

    @Test
    public void testQueryOverLazyReference() throws Exception {

        final ContainsPic cpk = new ContainsPic();
        final Pic p = new Pic();
        getDs().save(p);
        cpk.lazyPic = p;

        getDs().save(cpk);

        final Query<ContainsPic> query = getDs().createQuery(ContainsPic.class);
        assertEquals(1, query.field("lazyPic").equal(p).asList().size());
    }


    @Test
    public void testWhereCodeWScopeQuery() throws Exception {
        getDs().save(new PhotoWithKeywords());
        //        CodeWScope hasKeyword = new CodeWScope("for (kw in this.keywords) { if(kw.keyword == kwd) return true; } return false;
        // ", new BasicDBObject("kwd","california"));
        final CodeWScope hasKeyword = new CodeWScope("this.keywords != null", new BasicDBObject());
        assertNotNull(getDs().find(PhotoWithKeywords.class).where(hasKeyword).get());
    }

    @Test
    public void testWhereStringQuery() throws Exception {
        getDs().save(new PhotoWithKeywords());
        assertNotNull(getDs().find(PhotoWithKeywords.class).where("this.keywords != null").get());
    }

    @Test
    public void testWhereWithInvalidStringQuery() throws Exception {
        getDs().save(new PhotoWithKeywords());
        final CodeWScope hasKeyword = new CodeWScope("keywords != null", new BasicDBObject());
        try {
            // must fail
            assertNotNull(getDs().find(PhotoWithKeywords.class).where(hasKeyword.getCode()).get());
            Assert.fail("Invalid javascript magically isn't invalid anymore?");
        } catch (MongoInternalException e) {
            // fine
        } catch (MongoException e) {
            // fine
        }

    }

    @Test
    public void testRegexQuery() throws Exception {
        getDs().save(new PhotoWithKeywords());
        assertNotNull(getDs().find(PhotoWithKeywords.class)
                          .disableValidation()
                          .filter("keywords.keyword", Pattern.compile("california"))
                          .get());
        assertNull(getDs().find(PhotoWithKeywords.class, "keywords.keyword", Pattern.compile("blah")).get());
    }

    @Test
    public void testRegexInsensitiveQuery() throws Exception {
        getDs().save(new PhotoWithKeywords());
        final Pattern p = Pattern.compile("(?i)caLifornia");
        assertNotNull(getDs().find(PhotoWithKeywords.class).disableValidation().filter("keywords.keyword", p).get());
        assertNull(getDs().find(PhotoWithKeywords.class, "keywords.keyword", Pattern.compile("blah")).get());
    }

    @Test
    public void testDeepQuery() throws Exception {
        getDs().save(new PhotoWithKeywords());
        assertNotNull(getDs().find(PhotoWithKeywords.class, "keywords.keyword", "california").get());
        assertNull(getDs().find(PhotoWithKeywords.class, "keywords.keyword", "not").get());
    }

    @Test
    public void testDeepQueryWithRenamedFields() throws Exception {
        getDs().save(new PhotoWithKeywords());
        assertNotNull(getDs().find(PhotoWithKeywords.class, "keywords.keyword", "california").get());
        assertNull(getDs().find(PhotoWithKeywords.class, "keywords.keyword", "not").get());
    }

    @Test
    public void testNegativeBatchSize() throws Exception {
        getDs().delete(getDs().find(PhotoWithKeywords.class));
        getDs().save(new PhotoWithKeywords("scott", "hernandez"),
                     new PhotoWithKeywords("scott", "hernandez"),
                     new PhotoWithKeywords("scott", "hernandez"));
        getDs().save(new PhotoWithKeywords("1", "2"), new PhotoWithKeywords("3", "4"), new PhotoWithKeywords("5", "6"));
        final List<PhotoWithKeywords> list = getDs().find(PhotoWithKeywords.class)
                                                 .batchSize(-2)
                                                 .asList();
        Assert.assertEquals(2, list.size());
    }

    @Test
    public void testSnapshottedQuery() throws Exception {
        getDs().delete(getDs().find(PhotoWithKeywords.class));
        getDs().save(new PhotoWithKeywords("scott", "hernandez"),
                     new PhotoWithKeywords("scott", "hernandez"),
                     new PhotoWithKeywords("scott", "hernandez"));
        final Iterator<PhotoWithKeywords> it = getDs().find(PhotoWithKeywords.class, "keywords.keyword", "scott")
                                                   .enableSnapshotMode()
                                                   .batchSize(2)
                                                   .iterator();
        getDs().save(new PhotoWithKeywords("1", "2"), new PhotoWithKeywords("3", "4"), new PhotoWithKeywords("5", "6"));

        PhotoWithKeywords pwkLoaded;
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
        //okay, now we should getMore...
        assertTrue(it.hasNext());
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
        assertTrue(!it.hasNext());
    }

    @Test
    public void testNonSnapshottedQuery() throws Exception {
        getDs().delete(getDs().find(PhotoWithKeywords.class));
        getDs().save(new PhotoWithKeywords("scott", "hernandez"),
                     new PhotoWithKeywords("scott", "hernandez"),
                     new PhotoWithKeywords("scott", "hernandez"));
        final Iterator<PhotoWithKeywords> it = getDs().find(PhotoWithKeywords.class).enableSnapshotMode().batchSize(2).iterator();
        getDs().save(new PhotoWithKeywords("1", "2"), new PhotoWithKeywords("3", "4"), new PhotoWithKeywords("5", "6"));

        PhotoWithKeywords pwkLoaded;
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
        //okay, now we should getMore...
        assertTrue(it.hasNext());
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
        assertTrue(it.hasNext());
        pwkLoaded = it.next();
        assertNotNull(pwkLoaded);
    }

    @Test
    public void testRetrievedFields() throws Exception {
        getDs().find(ContainsRenamedFields.class).retrievedFields(true, "first_name").get();
        getDs().find(ContainsRenamedFields.class).retrievedFields(true, "firstName").get();
        try {
            getDs().find(ContainsRenamedFields.class).retrievedFields(true, "bad field name").get();
            Assert.fail("Validation should have caught the bad field");
        } catch (ValidationException e) {
            // success!
        }
    }

    @Test
    public void testDBObjectOrQuery() throws Exception {
        final PhotoWithKeywords pwk = new PhotoWithKeywords("scott", "hernandez");
        getDs().save(pwk);

        final List<DBObject> orList = new ArrayList<DBObject>();
        orList.add(new BasicDBObject("keywords.keyword", "scott"));
        orList.add(new BasicDBObject("keywords.keyword", "ralph"));
        final BasicDBObject orQuery = new BasicDBObject("$or", orList);

        Query<PhotoWithKeywords> q = getAds().createQuery(PhotoWithKeywords.class, orQuery);
        assertEquals(1, q.countAll());

        q = getAds().createQuery(PhotoWithKeywords.class).disableValidation().filter("$or", orList);
        assertEquals(1, q.countAll());
    }

    @Test
    public void testFluentOrQuery() throws Exception {
        final PhotoWithKeywords pwk = new PhotoWithKeywords("scott", "hernandez");
        getDs().save(pwk);

        final Query<PhotoWithKeywords> q = getAds().createQuery(PhotoWithKeywords.class);
        q.or(q.criteria("keywords.keyword").equal("scott"), q.criteria("keywords.keyword").equal("ralph"));

        assertEquals(1, q.countAll());
    }

    @Test
    public void testFluentAndOrQuery() throws Exception {
        final PhotoWithKeywords pwk = new PhotoWithKeywords("scott", "hernandez");
        getDs().save(pwk);

        final Query<PhotoWithKeywords> q = getAds().createQuery(PhotoWithKeywords.class);
        q.and(q.or(q.criteria("keywords.keyword").equal("scott")), q.or(q.criteria("keywords.keyword").equal("hernandez")));

        assertEquals(1, q.countAll());
        final QueryImpl<PhotoWithKeywords> qi = (QueryImpl<PhotoWithKeywords>) q;
        final DBObject realCriteria = qi.prepareCursor().getQuery();
        assertTrue(realCriteria.containsField("$and"));

    }

    @Test
    public void testFluentAndQuery1() throws Exception {
        final PhotoWithKeywords pwk = new PhotoWithKeywords("scott", "hernandez");
        getDs().save(pwk);

        final Query<PhotoWithKeywords> q = getAds().createQuery(PhotoWithKeywords.class);
        q.and(q.criteria("keywords.keyword").hasThisOne("scott"),
              q.criteria("keywords.keyword").hasAnyOf(Arrays.asList("scott", "hernandez")));

        assertEquals(1, q.countAll());
        final QueryImpl<PhotoWithKeywords> qi = (QueryImpl<PhotoWithKeywords>) q;
        final DBObject realCriteria = qi.prepareCursor().getQuery();
        assertTrue(realCriteria.containsField("$and"));

    }

    @Test
    public void testFluentNotQuery() throws Exception {
        final PhotoWithKeywords pwk = new PhotoWithKeywords("scott", "hernandez");
        getDs().save(pwk);

        final Query<PhotoWithKeywords> query = getAds().createQuery(PhotoWithKeywords.class);
        query.criteria("keywords.keyword").not().startsWith("ralph");

        assertEquals(1, query.countAll());
    }

    @Test
    public void testNotGeneratesCorrectQueryForRegex() throws Exception {
        // given
        final Query<PhotoWithKeywords> query = getAds().createQuery(PhotoWithKeywords.class);

        // when
        query.criteria("keywords.keyword").not().startsWith("ralph");

        // then
        assertThat(query.toString(), jsonEqual("{ keywords.keyword: { $not: { $regex: '^ralph'} } }"));
    }

    @Test
    public void testNotGeneratesCorrectQueryForGreaterThan() throws Exception {
        // given
        final Query<Keyword> query = getAds().createQuery(Keyword.class);

        // when
        query.criteria("score").not().greaterThan(7);

        // then
        assertThat(query.toString(), jsonEqual("{ score: { $not: { $gt: 7} } }"));
    }

    @Test
    public void testCorrectQueryForNotWithSizeEqIssue514() {
        // given
        Query<PhotoWithKeywords> query = getAds().createQuery(PhotoWithKeywords.class);

        // when
        query.field("keywords").not().sizeEq(3);

        // then
        assertThat(query.toString(), jsonEqual("{ keywords: { $not: { $size: 3 } } }"));
    }

    @Test
    public void testSizeEqQuery() {
        // given
        Query<PhotoWithKeywords> query = getAds().createQuery(PhotoWithKeywords.class);

        // when
        query.field("keywords").sizeEq(3);

        // then
        assertThat(query.toString(), jsonEqual("{ keywords: { $size: 3 } }"));
    }

    @Test
    public void testIdFieldNameQuery() throws Exception {
        final PhotoWithKeywords pwk = new PhotoWithKeywords("scott", "hernandez");
        getDs().save(pwk);

        final PhotoWithKeywords pwkLoaded = getDs().find(PhotoWithKeywords.class, "id !=", "scott").get();
        assertNotNull(pwkLoaded);
    }

    @Test
    public void testComplexIdQuery() throws Exception {
        final CustomId cId = new CustomId();
        cId.setId(new ObjectId());
        cId.setType("banker");

        final UsesCustomIdObject object = new UsesCustomIdObject();
        object.setId(cId);
        object.setText("hllo");
        getDs().save(object);

        assertNotNull(getDs().find(UsesCustomIdObject.class, "_id.type", "banker").get());
    }

    @Test
    public void testComplexIdQueryWithRenamedField() throws Exception {
        final CustomId cId = new CustomId();
        cId.setId(new ObjectId());
        cId.setType("banker");

        final UsesCustomIdObject object = new UsesCustomIdObject();
        object.setId(cId);
        object.setText("hllo");
        getDs().save(object);

        assertNotNull(getDs().find(UsesCustomIdObject.class, "_id.t", "banker").get());
    }

    @Test
    public void testQBE() throws Exception {
        final CustomId cId = new CustomId();
        cId.setId(new ObjectId());
        cId.setType("banker");

        final UsesCustomIdObject object = new UsesCustomIdObject();
        object.setId(cId);
        object.setText("hllo");
        getDs().save(object);
        final UsesCustomIdObject loaded;

        // Add back if/when query by example for embedded fields is supported (require dotting each field).
        // CustomId exId = new CustomId();
        // exId.type = cId.type;
        // loaded = getDs().find(UsesCustomIdObject.class, "_id", exId).get();
        // assertNotNull(loaded);

        final UsesCustomIdObject ex = new UsesCustomIdObject();
        ex.setText(object.getText());
        loaded = getDs().queryByExample(ex).get();
        assertNotNull(loaded);
    }

    @Test
    public void testDeepQueryWithBadArgs() throws Exception {
        getDs().save(new PhotoWithKeywords());
        PhotoWithKeywords p = getDs().find(PhotoWithKeywords.class, "keywords.keyword", 1).get();
        assertNull(p);
        p = getDs().find(PhotoWithKeywords.class, "keywords.keyword", "california".getBytes()).get();
        assertNull(p);
        p = getDs().find(PhotoWithKeywords.class, "keywords.keyword", null).get();
        assertNull(p);
    }


    @Test
    public void testElemMatchQuery() throws Exception {
        final PhotoWithKeywords pwk1 = new PhotoWithKeywords();
        final PhotoWithKeywords pwk2 = new PhotoWithKeywords("Scott", "Joe", "Sarah");

        getDs().save(pwk1, pwk2);
        final PhotoWithKeywords pwkScott = getDs().find(PhotoWithKeywords.class)
                                               .field("keywords")
                                               .hasThisElement(new Keyword("Scott"))
                                               .get();
        assertNotNull(pwkScott);
        // TODO add back when $and is done (> 1.5)
        // PhotoWithKeywords pwkScottSarah= getDs().find(PhotoWithKeywords.class).field("keywords").hasThisElement(new Keyword[] {new
        // Keyword("Scott"), new Keyword("Joe")}).get();
        // assertNotNull(pwkScottSarah);
        final PhotoWithKeywords pwkBad = getDs().find(PhotoWithKeywords.class).field("keywords").hasThisElement(new Keyword("Randy")).get();
        assertNull(pwkBad);

    }

    @Test
    public void testKeyList() throws Exception {
        final Rectangle rect = new Rectangle(1000, 1);
        final Key<Rectangle> rectKey = getDs().save(rect);

        assertEquals(rectKey.getId(), rect.getId());

        final FacebookUser fbUser1 = new FacebookUser(1, "scott");
        final FacebookUser fbUser2 = new FacebookUser(2, "tom");
        final FacebookUser fbUser3 = new FacebookUser(3, "oli");
        final FacebookUser fbUser4 = new FacebookUser(4, "frank");
        final Iterable<Key<FacebookUser>> fbKeys = getDs().save(fbUser1, fbUser2, fbUser3, fbUser4);
        assertEquals(1, fbUser1.getId());

        final List<Key<FacebookUser>> fbUserKeys = new ArrayList<Key<FacebookUser>>();
        for (final Key<FacebookUser> key : fbKeys) {
            fbUserKeys.add(key);
        }

        assertEquals(fbUser1.getId(), fbUserKeys.get(0).getId());
        assertEquals(fbUser2.getId(), fbUserKeys.get(1).getId());
        assertEquals(fbUser3.getId(), fbUserKeys.get(2).getId());
        assertEquals(fbUser4.getId(), fbUserKeys.get(3).getId());

        final KeysKeysKeys k1 = new KeysKeysKeys(rectKey, fbUserKeys);
        final Key<KeysKeysKeys> k1Key = getDs().save(k1);
        assertEquals(k1.getId(), k1Key.getId());

        final KeysKeysKeys k1Loaded = getDs().get(k1);
        for (final Key<FacebookUser> key : k1Loaded.getUsers()) {
            assertNotNull(key.getId());
        }

        assertNotNull(k1Loaded.getRect().getId());
    }

    @Test
    public void testKeyListLookups() throws Exception {
        final FacebookUser fbUser1 = new FacebookUser(1, "scott");
        final FacebookUser fbUser2 = new FacebookUser(2, "tom");
        final FacebookUser fbUser3 = new FacebookUser(3, "oli");
        final FacebookUser fbUser4 = new FacebookUser(4, "frank");
        final Iterable<Key<FacebookUser>> fbKeys = getDs().save(fbUser1, fbUser2, fbUser3, fbUser4);
        assertEquals(1, fbUser1.getId());

        final List<Key<FacebookUser>> fbUserKeys = new ArrayList<Key<FacebookUser>>();
        for (final Key<FacebookUser> key : fbKeys) {
            fbUserKeys.add(key);
        }

        assertEquals(fbUser1.getId(), fbUserKeys.get(0).getId());
        assertEquals(fbUser2.getId(), fbUserKeys.get(1).getId());
        assertEquals(fbUser3.getId(), fbUserKeys.get(2).getId());
        assertEquals(fbUser4.getId(), fbUserKeys.get(3).getId());

        final KeysKeysKeys k1 = new KeysKeysKeys(null, fbUserKeys);
        final Key<KeysKeysKeys> k1Key = getDs().save(k1);
        assertEquals(k1.getId(), k1Key.getId());

        final KeysKeysKeys k1Reloaded = getDs().get(k1);
        final KeysKeysKeys k1Loaded = getDs().getByKey(KeysKeysKeys.class, k1Key);
        assertNotNull(k1Reloaded);
        assertNotNull(k1Loaded);
        for (final Key<FacebookUser> key : k1Loaded.getUsers()) {
            assertNotNull(key.getId());
        }

        assertEquals(4, k1Loaded.getUsers().size());

        final List<FacebookUser> fbUsers = getDs().getByKeys(FacebookUser.class, k1Loaded.getUsers());
        assertEquals(4, fbUsers.size());
        for (final FacebookUser fbUser : fbUsers) {
            assertNotNull(fbUser);
            assertNotNull(fbUser.getId());
            assertNotNull(fbUser.getUsername());
        }
    }

    @Test
    public void testGetByKeysHetero() throws Exception {
        final FacebookUser fbU = new FacebookUser(1, "scott");
        final Rectangle r = new Rectangle(1, 1);
        final Iterable<Key<Object>> keys = getDs().save(fbU, r);
        final List<Object> entities = getDs().getByKeys(keys);
        assertNotNull(entities);
        assertEquals(2, entities.size());
        int userCount = 0;
        int rectCount = 0;
        for (final Object o : entities) {
            if (o instanceof Rectangle) {
                rectCount++;
            } else if (o instanceof FacebookUser) {
                userCount++;
            }
        }
        assertEquals(1, rectCount);
        assertEquals(1, userCount);
    }

    @Test
    public void testNonexistentGet() throws Exception {
        assertNull(getDs().get(Hotel.class, -1));
    }

    @Test
    public void testNonexistentFindGet() throws Exception {
        assertNull(getDs().find(Hotel.class, "_id", -1).get());
    }

    @Test
    public void testSimpleSort() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(3, 8), new Rectangle(6, 10), new Rectangle(10, 10),
                                   new Rectangle(10, 1)};
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        Rectangle r1 = getDs().find(Rectangle.class).limit(1).order("width").get();
        assertNotNull(r1);
        assertEquals(1, r1.getWidth(), 0);

        r1 = getDs().find(Rectangle.class).limit(1).order("-width").get();
        assertNotNull(r1);
        assertEquals(10, r1.getWidth(), 0);
    }

    @Test
    public void testAliasedFieldSort() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(3, 8), new Rectangle(6, 10), new Rectangle(10, 10),
                                   new Rectangle(10, 1)};
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        Rectangle r1 = getDs().find(Rectangle.class).limit(1).order("w").get();
        assertNotNull(r1);
        assertEquals(1, r1.getWidth(), 0);

        r1 = getDs().find(Rectangle.class).limit(1).order("-w").get();
        assertNotNull(r1);
        assertEquals(10, r1.getWidth(), 0);
    }

    @Test
    public void testCompoundSort() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(3, 8), new Rectangle(6, 10), new Rectangle(10, 10),
                                   new Rectangle(10, 1)};
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        Rectangle r1 = getDs().find(Rectangle.class).order("width,-height").get();
        assertNotNull(r1);
        assertEquals(1, r1.getWidth(), 0);
        assertEquals(10, r1.getHeight(), 0);

        r1 = getDs().find(Rectangle.class).order("-height, -width").get();
        assertNotNull(r1);
        assertEquals(10, r1.getWidth(), 0);
        assertEquals(10, r1.getHeight(), 0);
    }

    @Test
    public void testQueryCount() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(1, 10), new Rectangle(1, 10), new Rectangle(10, 10),
                                   new Rectangle(10, 10)};
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        assertEquals(3, getDs().getCount(getDs().find(Rectangle.class, "height", 1D)));
        assertEquals(2, getDs().getCount(getDs().find(Rectangle.class, "height", 10D)));
        assertEquals(5, getDs().getCount(getDs().find(Rectangle.class, "width", 10D)));

    }

    @Test
    public void testDeleteQuery() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(1, 10), new Rectangle(1, 10), new Rectangle(10, 10),
                                   new Rectangle(10, 10)};
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        assertEquals(5, getDs().getCount(Rectangle.class));
        getDs().delete(getDs().find(Rectangle.class, "height", 1D));
        assertEquals(2, getDs().getCount(Rectangle.class));
    }

    @Test
    public void testIdRangeQuery() throws Exception {
        getDs().save(new HasIntId(1), new HasIntId(11), new HasIntId(12));
        assertEquals(2, getDs().find(HasIntId.class).filter("_id >", 5).filter("_id <", 20).countAll());
        assertEquals(1, getDs().find(HasIntId.class).field("_id").greaterThan(0).field("_id").lessThan(11).countAll());
    }


    @Test
    public void testRangeQuery() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(4, 2), new Rectangle(6, 10), new Rectangle(8, 5),
                                   new Rectangle(10, 4)
        };
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        assertEquals(4, getDs().getCount(getDs().createQuery(Rectangle.class).filter("height >", 3)));
        assertEquals(3, getDs().getCount(getDs().createQuery(Rectangle.class).filter("height >", 3).filter("height <", 10)));
        assertEquals(1, getDs().getCount(getDs().createQuery(Rectangle.class).filter("height >", 9).filter("width <", 5)));
        assertEquals(3, getDs().getCount(getDs().createQuery(Rectangle.class).filter("height <", 7)));
    }

    @Test
    public void testComplexRangeQuery() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(4, 2), new Rectangle(6, 10), new Rectangle(8, 5),
                                   new Rectangle(10, 4)
        };
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        assertEquals(2, getDs().getCount(getDs().createQuery(Rectangle.class).filter("height >", 3).filter("height <", 8)));
        assertEquals(1, getDs().getCount(getDs().createQuery(Rectangle.class)
                                             .filter("height >", 3)
                                             .filter("height <", 8)
                                             .filter("width", 10)));
    }

    @Test
    public void testCombinationQuery() throws Exception {
        final Rectangle[] array = {new Rectangle(1, 10), new Rectangle(4, 2), new Rectangle(6, 10), new Rectangle(8, 5),
                                   new Rectangle(10, 4)};
        for (final Rectangle rect : array) {
            getDs().save(rect);
        }

        Query<Rectangle> q;

        q = getDs().createQuery(Rectangle.class);
        q.and(q.criteria("width").equal(10), q.criteria("height").equal(1));

        assertEquals(1, getDs().getCount(q));

        q = getDs().createQuery(Rectangle.class);
        q.or(q.criteria("width").equal(10), q.criteria("height").equal(10));

        assertEquals(3, getDs().getCount(q));

        q = getDs().createQuery(Rectangle.class);
        q.or(q.criteria("width").equal(10), q.and(q.criteria("width").equal(5), q.criteria("height").equal(8)));

        assertEquals(3, getDs().getCount(q));
    }

    @Test
    public void testInQuery() throws Exception {
        final Photo photo = new Photo();
        photo.keywords = new ArrayList<String>();
        photo.keywords.add("red");
        photo.keywords.add("blue");
        photo.keywords.add("green");
        getDs().save(photo);

        final Set<String> keywords = new HashSet<String>();
        keywords.add("red");
        keywords.add("yellow");
        final Photo photoFound = getDs().find(Photo.class).field("keywords").in(keywords).get();
        assertNotNull(photoFound);
    }

    @Test
    public void testInQueryWithObjects() throws Exception {
        getDs().save(new PhotoWithKeywords(), new PhotoWithKeywords("Scott", "Joe", "Sarah"));

        final Set<Keyword> keywords = new HashSet<Keyword>();
        keywords.add(new Keyword("Scott"));
        keywords.add(new Keyword("Randy"));
        final PhotoWithKeywords pwkFound = getDs().find(PhotoWithKeywords.class).field("keywords").in(keywords).get();
        assertNotNull(pwkFound);
    }

    @Test
    public void multiKeyValueQueries() {
        getMorphia().map(KeyValue.class);
        getDs().ensureIndexes(KeyValue.class);
        final KeyValue value = new KeyValue();
        final List<Object> keys = Arrays.<Object>asList("key1", "key2");
        value.key = keys;
        getDs().save(value);

        final Query<KeyValue> query = getDs().createQuery(KeyValue.class).field("key").hasAnyOf(keys);
        Assert.assertTrue(query.toString().replaceAll("\\s", "").contains("{\"$in\":[\"key1\",\"key2\"]"));
        Assert.assertEquals(query.get().id, value.id);
    }

    @Test
    public void genericMultiKeyValueQueries() {
        getMorphia().map(GenericKeyValue.class);
        getDs().ensureIndexes(GenericKeyValue.class);
        final GenericKeyValue<String> value = new GenericKeyValue<String>();
        final List<Object> keys = Arrays.<Object>asList("key1", "key2");
        value.key = keys;
        getDs().save(value);

        final Query<GenericKeyValue> query = getDs().createQuery(GenericKeyValue.class).field("key").hasAnyOf(keys);
        Assert.assertTrue(query.toString().replaceAll("\\s", "").contains("{\"$in\":[\"key1\",\"key2\"]"));
        Assert.assertEquals(query.get().id, value.id);
    }

    @Test
    public void referenceKeys() {
        final ReferenceKey key1 = new ReferenceKey("key1");

        final Pic pic1 = new Pic("pic1");
        final Pic pic2 = new Pic("pic2");
        final Pic pic3 = new Pic("pic3");
        final Pic pic4 = new Pic("pic4");
        getDs().save(key1, pic1, pic2, pic3, pic4);

        final ReferenceKeyValue value = new ReferenceKeyValue();
        value.id = key1;

        final Key<ReferenceKeyValue> key = getDs().save(value);

        final ReferenceKeyValue byKey = getDs().getByKey(ReferenceKeyValue.class, key);
        Assert.assertEquals(value.id, byKey.id);
    }

    @Test
    public void maxScan() {
        final Pic pic1 = new Pic("pic1");
        final Pic pic2 = new Pic("pic2");
        final Pic pic3 = new Pic("pic3");
        final Pic pic4 = new Pic("pic4");

        getDs().save(pic1, pic2, pic3, pic4);

        Assert.assertEquals(2, getDs().createQuery(Pic.class).maxScan(2).asList().size());
        Assert.assertEquals(4, getDs().createQuery(Pic.class).asList().size());
    }

    @Test
    public void testExplainPlanIsReturnedAndContainsCorrectValueForN() {
        // Given
        getDs().save(new Pic("pic1"), new Pic("pic2"), new Pic("pic3"), new Pic("pic4"));

        // When
        Map<String, Object> explainResult = getDs().createQuery(Pic.class).explain();

        // Then
        Assert.assertEquals(4, explainResult.get("n"));
    }

    @Test
    public void testSettingACommentInsertsCommentIntoProfileCollectionWhenProfilingIsTurnedOn() {
        // given
        getDs().save(new Pic("pic1"), new Pic("pic2"), new Pic("pic3"), new Pic("pic4"));

        getDb().command(new BasicDBObject("profile", 2));
        String expectedComment = "test comment";

        // when
        getDs().createQuery(Pic.class).comment(expectedComment).asList();

        // then
        DBCollection profileCollection = getDb().getCollection("system.profile");
        assertNotEquals(0, profileCollection.count());
        DBObject profileRecord = profileCollection.findOne(new BasicDBObject("op", "query")
                                                           .append("ns", getDs().getCollection(Pic.class).getFullName()));
        assertEquals(expectedComment, ((DBObject) profileRecord.get("query")).get("$comment"));

        // finally
        turnOffProfilingAndDropProfileCollection();
    }

    @Test
    public void testShouldReturnOnlyTheFieldThatWasInTheIndexUsedForTheFindWhenReturnKeyIsUsed() {
        // Given
        // put some documents into the collection
        getDs().save(new Pic("pic1"), new Pic("pic2"), new Pic("pic3"), new Pic("pic4"));
        //set an index on the field "name"
        getDs().ensureIndex(Pic.class, "name");

        // When
        // find a document by using a search on the field in the index
        Query<Pic> query = getDs().createQuery(Pic.class).returnKey().field("name").equal("pic2");

        // Then
        Pic foundItem = query.get();
        assertNotNull(foundItem);
        assertThat("Name should be populated", foundItem.getName(), is("pic2"));
        assertNull("ID should not be populated", foundItem.getId());
    }
   
    @After
    public void tearDown() {
        turnOffProfilingAndDropProfileCollection();
        super.tearDown();
    }

    private void turnOffProfilingAndDropProfileCollection() {
        getDb().command(new BasicDBObject("profile", 0));
        DBCollection profileCollection = getDb().getCollection("system.profile");
        profileCollection.drop();
    }
}
TOP

Related Classes of org.mongodb.morphia.TestQuery$Keyword

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.