def test_limit_skip_index(self):
        fields = ["field1"]
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is True

        fields = ["field2"]
        ret = self.db.create_index(fields, name="idx_02")
        assert ret is True

        fields = ["field3"]
        ret = self.db.create_index(fields, name="idx_03")
        assert ret is True

        skip_add = 0

        if mango.has_text_service():
            skip_add = 1

        assert len(self.db.list_indexes(limit=2)) == 2
        assert len(self.db.list_indexes(limit=5, skip=4)) == 2 + skip_add
        assert len(self.db.list_indexes(skip=5)) == 1 + skip_add
        assert len(self.db.list_indexes(skip=6)) == 0 + skip_add
        assert len(self.db.list_indexes(skip=100)) == 0
        assert len(self.db.list_indexes(limit=10000000)) == 6 + skip_add

        try:
            self.db.list_indexes(skip=-1)
        except Exception, e:
            assert e.response.status_code == 500
    def test_limit_skip_index(self):
        fields = ["field1"]
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is True

        fields = ["field2"]
        ret = self.db.create_index(fields, name="idx_02")
        assert ret is True

        fields = ["field3"]
        ret = self.db.create_index(fields, name="idx_03")
        assert ret is True

        skip_add = 0

        if mango.has_text_service():
            skip_add = 1

        assert len(self.db.list_indexes(limit=2)) == 2
        assert len(self.db.list_indexes(limit=5,skip=4)) == 2 + skip_add
        assert len(self.db.list_indexes(skip=5)) == 1 + skip_add
        assert len(self.db.list_indexes(skip=6)) == 0 + skip_add
        assert len(self.db.list_indexes(skip=100)) == 0
        assert len(self.db.list_indexes(limit=10000000)) == 6 + skip_add

        try:
            self.db.list_indexes(skip=-1)
        except Exception, e:
            assert e.response.status_code == 500
 def setUpClass(klass):
     super(DisableIndexArrayLengthsTest, klass).setUpClass()
     if mango.has_text_service():
         klass.db.create_text_index(
             ddoc="disable_index_array_lengths", analyzer="keyword", index_array_lengths=False
         )
         klass.db.create_text_index(
             ddoc="explicit_enable_index_array_lengths", analyzer="keyword", index_array_lengths=True
         )
 def setUpClass(klass):
     super(TextIndexSelectionTests, klass).setUpClass()
     if mango.has_text_service():
         user_docs.add_text_indexes(klass.db, {})
        # as in test above, use a selector that doesn't overlap with the index
        # due to an explicit exists clause
        selector = {
            "company": "Pharmex",
            "manager": {"$exists": False}
        }
        docs = self.db.find(selector)
        self.assertEqual(len(docs), 1)
        self.assertEqual(docs[0]["company"], "Pharmex")
        self.assertNotIn("manager", docs[0])

        resp_explain = self.db.find(selector, explain=True)
        self.assertEqual(resp_explain["index"]["type"], "special")


@unittest.skipUnless(mango.has_text_service(), "requires text service")
class TextIndexSelectionTests(mango.UserDocsTests):

    @classmethod
    def setUpClass(klass):
        super(TextIndexSelectionTests, klass).setUpClass()
        if mango.has_text_service():
            user_docs.add_text_indexes(klass.db, {})

    def test_with_text(self):
        resp = self.db.find({
                "$text" : "Stephanie",
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            }, explain=True)
        self.assertEqual(resp["index"]["type"], "text")
Beispiel #6
0
 def setUpClass(klass):
     super(NumStringTests, klass).setUpClass()
     klass.db.recreate()
     if mango.has_text_service():
         klass.db.create_text_index()
Beispiel #7
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.

import json
import mango
import unittest
import user_docs
import math
from hypothesis import given, assume, example
import hypothesis.strategies as st

@unittest.skipIf(mango.has_text_service(), "text service exists")
class TextIndexCheckTests(mango.DbPerClass):

    def test_create_text_index(self):
        body = json.dumps({
            'index': {
            },
            'type': 'text'
        })
        resp = self.db.sess.post(self.db.path("_index"), data=body)
        assert resp.status_code == 503, resp

@unittest.skipUnless(mango.has_text_service(), "requires text service")
class BasicTextTests(mango.UserDocsTextTests):

    def test_simple(self):
class IndexCrudTests(mango.DbPerClass):
    def setUp(self):
        self.db.recreate()

    def test_bad_fields(self):
        bad_fields = [
            None, True, False, "bing", 2.0, {
                "foo": "bar"
            }, [{
                "foo": 2
            }], [{
                "foo": "asc",
                "bar": "desc"
            }], [{
                "foo": "asc"
            }, {
                "bar": "desc"
            }], [""]
        ]
        for fields in bad_fields:
            try:
                self.db.create_index(fields)
            except Exception as e:
                assert e.response.status_code == 400
            else:
                raise AssertionError("bad create index")

    def test_bad_types(self):
        bad_types = [
            None,
            True,
            False,
            1.5,
            "foo",  # Future support
            "geo",  # Future support
            {
                "foo": "bar"
            },
            ["baz", 3.0]
        ]
        for bt in bad_types:
            try:
                self.db.create_index(["foo"], idx_type=bt)
            except Exception as e:
                assert e.response.status_code == 400, (bt,
                                                       e.response.status_code)
            else:
                raise AssertionError("bad create index")

    def test_bad_names(self):
        bad_names = [True, False, 1.5, {"foo": "bar"}, [None, False]]
        for bn in bad_names:
            try:
                self.db.create_index(["foo"], name=bn)
            except Exception as e:
                assert e.response.status_code == 400
            else:
                raise AssertionError("bad create index")
            try:
                self.db.create_index(["foo"], ddoc=bn)
            except Exception as e:
                assert e.response.status_code == 400
            else:
                raise AssertionError("bad create index")

    def test_create_idx_01(self):
        fields = ["foo", "bar"]
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is True
        for idx in self.db.list_indexes():
            if idx["name"] != "idx_01":
                continue
            assert idx["def"]["fields"] == [{"foo": "asc"}, {"bar": "asc"}]
            return
        raise AssertionError("index not created")

    def test_create_idx_01_exists(self):
        fields = ["foo", "bar"]
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is True
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is False

    def test_create_idx_02(self):
        fields = ["baz", "foo"]
        ret = self.db.create_index(fields, name="idx_02")
        assert ret is True
        for idx in self.db.list_indexes():
            if idx["name"] != "idx_02":
                continue
            assert idx["def"]["fields"] == [{"baz": "asc"}, {"foo": "asc"}]
            return
        raise AssertionError("index not created")

    def test_read_idx_doc(self):
        self.db.create_index(["foo", "bar"], name="idx_01")
        self.db.create_index(["hello", "bar"])
        for idx in self.db.list_indexes():
            if idx["type"] == "special":
                continue
            ddocid = idx["ddoc"]
            doc = self.db.open_doc(ddocid)
            assert doc["_id"] == ddocid
            info = self.db.ddoc_info(ddocid)
            assert info["name"] == ddocid.split('_design/')[-1]

    def test_delete_idx_escaped(self):
        self.db.create_index(["foo", "bar"], name="idx_01")
        pre_indexes = self.db.list_indexes()
        ret = self.db.create_index(["bing"], name="idx_del_1")
        assert ret is True
        for idx in self.db.list_indexes():
            if idx["name"] != "idx_del_1":
                continue
            assert idx["def"]["fields"] == [{"bing": "asc"}]
            self.db.delete_index(idx["ddoc"].replace("/", "%2F"), idx["name"])
        post_indexes = self.db.list_indexes()
        assert pre_indexes == post_indexes

    def test_delete_idx_unescaped(self):
        pre_indexes = self.db.list_indexes()
        ret = self.db.create_index(["bing"], name="idx_del_2")
        assert ret is True
        for idx in self.db.list_indexes():
            if idx["name"] != "idx_del_2":
                continue
            assert idx["def"]["fields"] == [{"bing": "asc"}]
            self.db.delete_index(idx["ddoc"], idx["name"])
        post_indexes = self.db.list_indexes()
        assert pre_indexes == post_indexes

    def test_delete_idx_no_design(self):
        pre_indexes = self.db.list_indexes()
        ret = self.db.create_index(["bing"], name="idx_del_3")
        assert ret is True
        for idx in self.db.list_indexes():
            if idx["name"] != "idx_del_3":
                continue
            assert idx["def"]["fields"] == [{"bing": "asc"}]
            self.db.delete_index(idx["ddoc"].split("/")[-1], idx["name"])
        post_indexes = self.db.list_indexes()
        assert pre_indexes == post_indexes

    def test_bulk_delete(self):
        fields = ["field1"]
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is True

        fields = ["field2"]
        ret = self.db.create_index(fields, name="idx_02")
        assert ret is True

        fields = ["field3"]
        ret = self.db.create_index(fields, name="idx_03")
        assert ret is True

        docids = []

        for idx in self.db.list_indexes():
            if idx["ddoc"] is not None:
                docids.append(idx["ddoc"])

        docids.append("_design/this_is_not_an_index_name")

        ret = self.db.bulk_delete(docids)

        assert ret["fail"][0]["id"] == "_design/this_is_not_an_index_name"
        assert len(ret["success"]) == 3

        for idx in self.db.list_indexes():
            assert idx["type"] != "json"
            assert idx["type"] != "text"

    def test_recreate_index(self):
        pre_indexes = self.db.list_indexes()
        for i in range(5):
            ret = self.db.create_index(["bing"], name="idx_recreate")
            assert ret is True
            for idx in self.db.list_indexes():
                if idx["name"] != "idx_recreate":
                    continue
                assert idx["def"]["fields"] == [{"bing": "asc"}]
                self.db.delete_index(idx["ddoc"], idx["name"])
                break
            post_indexes = self.db.list_indexes()
            assert pre_indexes == post_indexes

    def test_delete_misisng(self):
        # Missing design doc
        try:
            self.db.delete_index("this_is_not_a_design_doc_id", "foo")
        except Exception as e:
            assert e.response.status_code == 404
        else:
            raise AssertionError("bad index delete")

        # Missing view name
        ret = self.db.create_index(["fields"], name="idx_01")
        indexes = self.db.list_indexes()
        not_special = [idx for idx in indexes if idx["type"] != "special"]
        idx = random.choice(not_special)
        ddocid = idx["ddoc"].split("/")[-1]
        try:
            self.db.delete_index(ddocid, "this_is_not_an_index_name")
        except Exception as e:
            assert e.response.status_code == 404
        else:
            raise AssertionError("bad index delete")

        # Bad view type
        try:
            self.db.delete_index(ddocid,
                                 idx["name"],
                                 idx_type="not_a_real_type")
        except Exception as e:
            assert e.response.status_code == 404
        else:
            raise AssertionError("bad index delete")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_create_text_idx(self):
        fields = [{
            "name": "stringidx",
            "type": "string"
        }, {
            "name": "booleanidx",
            "type": "boolean"
        }]
        ret = self.db.create_text_index(fields=fields, name="text_idx_01")
        assert ret is True
        for idx in self.db.list_indexes():
            if idx["name"] != "text_idx_01":
                continue
            assert idx["def"]["fields"] == [{
                "stringidx": "string"
            }, {
                "booleanidx": "boolean"
            }]
            return
        raise AssertionError("index not created")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_create_bad_text_idx(self):
        bad_fields = [
            True, False, "bing", 2.0, ["foo", "bar"], [{
                "name": "foo2"
            }], [{
                "name": "foo3",
                "type": "garbage"
            }], [{
                "type": "number"
            }], [{
                "name": "age",
                "type": "number"
            }, {
                "name": "bad"
            }], [{
                "name": "age",
                "type": "number"
            }, "bla"], [{
                "name": "",
                "type": "number"
            }, "bla"]
        ]
        for fields in bad_fields:
            try:
                self.db.create_text_index(fields=fields)
            except Exception as e:
                assert e.response.status_code == 400
            else:
                raise AssertionError("bad create text index")

    def test_limit_skip_index(self):
        fields = ["field1"]
        ret = self.db.create_index(fields, name="idx_01")
        assert ret is True

        fields = ["field2"]
        ret = self.db.create_index(fields, name="idx_02")
        assert ret is True

        fields = ["field3"]
        ret = self.db.create_index(fields, name="idx_03")
        assert ret is True

        fields = ["field4"]
        ret = self.db.create_index(fields, name="idx_04")
        assert ret is True

        fields = ["field5"]
        ret = self.db.create_index(fields, name="idx_05")
        assert ret is True

        skip_add = 0

        if mango.has_text_service():
            skip_add = 1

        assert len(self.db.list_indexes(limit=2)) == 2
        assert len(self.db.list_indexes(limit=5, skip=4)) == 2 + skip_add
        assert len(self.db.list_indexes(skip=5)) == 1 + skip_add
        assert len(self.db.list_indexes(skip=6)) == 0 + skip_add
        assert len(self.db.list_indexes(skip=100)) == 0
        assert len(self.db.list_indexes(limit=10000000)) == 6 + skip_add

        try:
            self.db.list_indexes(skip=-1)
        except Exception as e:
            assert e.response.status_code == 500

        try:
            self.db.list_indexes(limit=0)
        except Exception as e:
            assert e.response.status_code == 500
Beispiel #9
0
 def setUpClass(klass):
     super(MultiTextIndexSelectionTests, klass).setUpClass()
     if mango.has_text_service():
         klass.db.create_text_index(ddoc="foo", analyzer="keyword")
         klass.db.create_text_index(ddoc="bar", analyzer="email")
 def setUpClass(klass):
     super(KeyTests, klass).setUpClass()
     klass.db.save_docs(TEST_DOCS, w=3)
     klass.db.create_index(["type"], ddoc="view")
     if mango.has_text_service():
         klass.db.create_text_index(ddoc="text")
Beispiel #11
0
class OperatorTests:

    def assertUserIds(self, user_ids, docs):
        user_ids_returned = list(d["user_id"] for d in docs)
        user_ids.sort()
        user_ids_returned.sort()
        self.assertEqual(user_ids, user_ids_returned)

    def test_all(self):
        docs = self.db.find({
                "manager": True,
                "favorites": {"$all": ["Lisp", "Python"]}
            })
        self.assertEqual(len(docs), 4)
        user_ids = [2,12,9,14]
        self.assertUserIds(user_ids, docs)

    def test_all_non_array(self):
        docs = self.db.find({
                "manager": True,
                "location": {"$all": ["Ohai"]}
            })
        self.assertEqual(len(docs), 0)

    def test_elem_match(self):
        emdocs = [
            {
                "user_id": "a",
                "bang": [{
                    "foo": 1,
                    "bar": 2
                }]
            },
            {
                "user_id": "b",
                "bang": [{
                    "foo": 2,
                    "bam": True
                }]
            }
        ]
        self.db.save_docs(emdocs, w=3)
        docs = self.db.find({
            "_id": {"$gt": None},
            "bang": {"$elemMatch": {
                "foo": {"$gte": 1},
                "bam": True
            }}
        })
        self.assertEqual(len(docs), 1)
        self.assertEqual(docs[0]["user_id"], "b")

    def test_all_match(self):
        amdocs = [
            {
                "user_id": "a",
                "bang": [
                    {
                        "foo": 1,
                        "bar": 2
                    },
                    {
                        "foo": 3,
                        "bar": 4
                    }
                ]
            },
            {
                "user_id": "b",
                "bang": [
                    {
                        "foo": 1,
                        "bar": 2
                    },
                    {
                        "foo": 4,
                        "bar": 4
                    }
                ]
            }
        ]
        self.db.save_docs(amdocs, w=3)
        docs = self.db.find({
            "bang": {"$allMatch": {
                "foo": {"$mod": [2,1]},
                "bar": {"$mod": [2,0]}
            }}
        })
        self.assertEqual(len(docs), 1)
        self.assertEqual(docs[0]["user_id"], "a")
    
    def test_empty_all_match(self):
        amdocs = [
            {
                "bad_doc": "a",
                "emptybang": []
            }
        ]
        self.db.save_docs(amdocs, w=3)
        docs = self.db.find({
            "emptybang": {"$allMatch": {
                "foo": {"$eq": 2}
            }}
        })
        self.assertEqual(len(docs), 0)

    def test_in_operator_array(self):
        docs = self.db.find({
                "manager": True,
                "favorites": {"$in": ["Ruby", "Python"]}
            })
        self.assertUserIds([2,6,7,9,11,12,14], docs)

    def test_nin_operator_array(self):
        docs = self.db.find({
                "manager": True,
                "favorites": {"$nin": ["Erlang", "Python"]}
            })
        self.assertEqual(len(docs), 4)
        for doc in docs:
            if isinstance(doc["favorites"], list):
                self.assertNotIn("Erlang", doc["favorites"])
                self.assertNotIn("Python", doc["favorites"])

    def test_regex(self):
        docs = self.db.find({
                "age": {"$gt": 40},
                "location.state": {"$regex": "(?i)new.*"}
            })
        self.assertEqual(len(docs), 2)
        self.assertUserIds([2,10], docs)

    def test_exists_false(self):
        docs = self.db.find({
                "age": {"$gt": 0},
                "twitter": {"$exists": False}
            })
        user_ids = [2,3,5,6,7,8,10,11,12,14]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertNotIn("twitter", d)

    def test_eq_null_does_not_include_missing(self):
        docs = self.db.find({
                "age": {"$gt": 0},
                "twitter": None
            })
        user_ids = [9]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertEqual(d["twitter"], None)

    def test_ne_includes_null_but_not_missing(self):
        docs = self.db.find({
                "twitter": {"$ne": "notamatch"}
            })
        user_ids = [0,1,4,9,13]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertIn("twitter", d)

    def test_lt_includes_null_but_not_missing(self):
        docs = self.db.find({
                "twitter": {"$lt": 1}
            })
        user_ids = [9]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertEqual(d["twitter"], None)

    def test_lte_includes_null_but_not_missing(self):
        docs = self.db.find({
                "twitter": {"$lt": 1}
            })
        user_ids = [9]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertEqual(d["twitter"], None)

    def test_lte_null_includes_null_but_not_missing(self):
        docs = self.db.find({
                "twitter": {"$lte": None}
            })
        user_ids = [9]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertEqual(d["twitter"], None)

    def test_lte_at_z_except_null_excludes_null_and_missing(self):
        docs = self.db.find({
            "twitter": {"$and": [
                {"$lte": "@z"},
                {"$ne": None}
            ]}
        })
        user_ids = [0,1,4,13]
        self.assertUserIds(user_ids, docs)
        for d in docs:
            self.assertNotEqual(d["twitter"], None)

    def test_range_gte_null_includes_null_but_not_missing(self):
        docs = self.db.find({
                "twitter": {"$gte": None}
            })
        self.assertGreater(len(docs), 0)
        for d in docs:
            self.assertIn("twitter", d)

    def test_exists_false_returns_missing_but_not_null(self):
        docs = self.db.find({
                "twitter": {"$exists": False}
            })
        self.assertGreater(len(docs), 0)
        for d in docs:
            self.assertNotIn("twitter", d)
    
    @unittest.skipUnless(not mango.has_text_service(), 
    "text indexes do not support range queries across type boundaries")
    def test_lte_respsects_unicode_collation(self):
        docs = self.db.find({
                "ordered": {"$lte": "a"}
            })
        user_ids = [7,8,9,10,11,12]
        self.assertUserIds(user_ids, docs)
        
    @unittest.skipUnless(not mango.has_text_service(), 
    "text indexes do not support range queries across type boundaries")
    def test_gte_respsects_unicode_collation(self):
        docs = self.db.find({
                "ordered": {"$gte": "a"}
            })
        user_ids = [12,13,14]
        self.assertUserIds(user_ids, docs)
Beispiel #12
0
 def setUpClass(klass):
     super(KeyTests, klass).setUpClass()
     klass.db.save_docs(TEST_DOCS, w=3)
     klass.db.create_index(["type"], ddoc="view")
     if mango.has_text_service():
         klass.db.create_text_index(ddoc="text")
class IndexSelectionTests(mango.UserDocsTests):
    @classmethod
    def setUpClass(klass):
        super(IndexSelectionTests, klass).setUpClass()
        if mango.has_text_service():
            user_docs.add_text_indexes(klass.db, {})

    def test_basic(self):
        resp = self.db.find({"name.last": "A last name"}, explain=True)
        assert resp["index"]["type"] == "json"

    def test_with_and(self):
        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            },
            explain=True)
        assert resp["index"]["type"] == "json"

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_with_text(self):
        resp = self.db.find(
            {
                "$text": "Stephanie",
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            },
            explain=True)
        assert resp["index"]["type"] == "text"

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_no_view_index(self):
        resp = self.db.find({"name.first": "Ohai!"}, explain=True)
        assert resp["index"]["type"] == "text"

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_with_or(self):
        resp = self.db.find(
            {
                "$or": [{
                    "name.first": "Stephanie"
                }, {
                    "name.last": "This doesn't have to match anything."
                }]
            },
            explain=True)
        assert resp["index"]["type"] == "text"

    def test_use_most_columns(self):
        # ddoc id for the age index
        ddocid = "_design/ad3d537c03cd7c6a43cf8dff66ef70ea54c2b40f"
        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "Something or other",
                "age": {
                    "$gt": 1
                }
            },
            explain=True)
        assert resp["index"]["ddoc"] != "_design/" + ddocid

        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "Something or other",
                "age": {
                    "$gt": 1
                }
            },
            use_index=ddocid,
            explain=True)
        assert resp["index"]["ddoc"] == ddocid

    def test_use_most_columns(self):
        # ddoc id for the age index
        ddocid = "_design/ad3d537c03cd7c6a43cf8dff66ef70ea54c2b40f"
        try:
            self.db.find({}, use_index=ddocid)
        except Exception, e:
            assert e.response.status_code == 400
        else:
 def setUpClass(klass):
     super(NumStringTests, klass).setUpClass()
     klass.db.recreate()
     if mango.has_text_service():
         klass.db.create_text_index()
 def setUpClass(klass):
     super(MultiTextIndexSelectionTests, klass).setUpClass()
     if mango.has_text_service():
         klass.db.create_text_index(ddoc="foo", analyzer="keyword")
         klass.db.create_text_index(ddoc="bar", analyzer="email")
class IndexSelectorJson(mango.DbPerClass):
    def setUp(self):
        self.db.recreate()
        self.db.save_docs(copy.deepcopy(DOCS))

    def test_saves_partial_filter_selector_in_index(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_index(["location"], partial_filter_selector=selector)
        indexes = self.db.list_indexes()
        self.assertEqual(indexes[1]["def"]["partial_filter_selector"],
                         selector)

    def test_saves_selector_in_index_throws(self):
        selector = {"location": {"$gte": "FRA"}}
        try:
            self.db.create_index(["location"], selector=selector)
        except Exception as e:
            assert e.response.status_code == 400
        else:
            raise AssertionError("bad index creation")

    def test_uses_partial_index_for_query_selector(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_index(["location"],
                             partial_filter_selector=selector,
                             ddoc="Selected",
                             name="Selected")
        resp = self.db.find(selector, explain=True, use_index='Selected')
        self.assertEqual(resp["index"]["name"], "Selected")
        docs = self.db.find(selector, use_index='Selected')
        self.assertEqual(len(docs), 3)

    def test_uses_partial_index_with_different_selector(self):
        selector = {"location": {"$gte": "FRA"}}
        selector2 = {"location": {"$gte": "A"}}
        self.db.create_index(["location"],
                             partial_filter_selector=selector,
                             ddoc="Selected",
                             name="Selected")
        resp = self.db.find(selector2, explain=True, use_index='Selected')
        self.assertEqual(resp["index"]["name"], "Selected")
        docs = self.db.find(selector2, use_index='Selected')
        self.assertEqual(len(docs), 3)

    def test_doesnot_use_selector_when_not_specified(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_index(["location"],
                             partial_filter_selector=selector,
                             ddoc="Selected",
                             name="Selected")
        resp = self.db.find(selector, explain=True)
        self.assertEqual(resp["index"]["name"], "_all_docs")

    def test_doesnot_use_selector_when_not_specified_with_index(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_index(["location"],
                             partial_filter_selector=selector,
                             ddoc="Selected",
                             name="Selected")
        self.db.create_index(["location"], name="NotSelected")
        resp = self.db.find(selector, explain=True)
        self.assertEqual(resp["index"]["name"], "NotSelected")

    def test_old_selector_with_no_selector_still_supported(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.save_doc(oldschoolnoselectorddoc)
        resp = self.db.find(selector,
                            explain=True,
                            use_index='oldschoolnoselector')
        self.assertEqual(resp["index"]["name"], "oldschoolnoselector")
        docs = self.db.find(selector, use_index='oldschoolnoselector')
        self.assertEqual(len(docs), 3)

    def test_old_selector_still_supported(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.save_doc(oldschoolddoc)
        resp = self.db.find(selector, explain=True, use_index='oldschool')
        self.assertEqual(resp["index"]["name"], "oldschool")
        docs = self.db.find(selector, use_index='oldschool')
        self.assertEqual(len(docs), 3)

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_text_saves_partialfilterselector_in_index(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_text_index(fields=[{
            "name": "location",
            "type": "string"
        }],
                                  partial_filter_selector=selector)
        indexes = self.db.list_indexes()
        self.assertEqual(indexes[1]["def"]["partial_filter_selector"],
                         selector)

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_text_uses_partial_index_for_query_selector(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_text_index(fields=[{
            "name": "location",
            "type": "string"
        }],
                                  partial_filter_selector=selector,
                                  ddoc="Selected",
                                  name="Selected")
        resp = self.db.find(selector, explain=True, use_index='Selected')
        self.assertEqual(resp["index"]["name"], "Selected")
        docs = self.db.find(selector,
                            use_index='Selected',
                            fields=['_id', 'location'])
        self.assertEqual(len(docs), 3)

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_text_uses_partial_index_with_different_selector(self):
        selector = {"location": {"$gte": "FRA"}}
        selector2 = {"location": {"$gte": "A"}}
        self.db.create_text_index(fields=[{
            "name": "location",
            "type": "string"
        }],
                                  partial_filter_selector=selector,
                                  ddoc="Selected",
                                  name="Selected")
        resp = self.db.find(selector2, explain=True, use_index='Selected')
        self.assertEqual(resp["index"]["name"], "Selected")
        docs = self.db.find(selector2, use_index='Selected')
        self.assertEqual(len(docs), 3)

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_text_doesnot_use_selector_when_not_specified(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_text_index(fields=[{
            "name": "location",
            "type": "string"
        }],
                                  partial_filter_selector=selector,
                                  ddoc="Selected",
                                  name="Selected")
        resp = self.db.find(selector, explain=True)
        self.assertEqual(resp["index"]["name"], "_all_docs")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_text_doesnot_use_selector_when_not_specified_with_index(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.create_text_index(fields=[{
            "name": "location",
            "type": "string"
        }],
                                  partial_filter_selector=selector,
                                  ddoc="Selected",
                                  name="Selected")
        self.db.create_text_index(fields=[{
            "name": "location",
            "type": "string"
        }],
                                  name="NotSelected")
        resp = self.db.find(selector, explain=True)
        self.assertEqual(resp["index"]["name"], "NotSelected")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_text_old_selector_still_supported(self):
        selector = {"location": {"$gte": "FRA"}}
        self.db.save_doc(oldschoolddoctext)
        resp = self.db.find(selector, explain=True, use_index='oldschooltext')
        self.assertEqual(resp["index"]["name"], "oldschooltext")
        docs = self.db.find(selector, use_index='oldschooltext')
        self.assertEqual(len(docs), 3)
Beispiel #17
0
 def setUpClass(klass):
     super(TextIndexSelectionTests, klass).setUpClass()
     if mango.has_text_service():
         user_docs.add_text_indexes(klass.db, {})
Beispiel #18
0
class IndexSelectionTests(mango.UserDocsTests):
    @classmethod
    def setUpClass(klass):
        super(IndexSelectionTests, klass).setUpClass()
        if mango.has_text_service():
            user_docs.add_text_indexes(klass.db, {})

    def test_basic(self):
        resp = self.db.find({"name.last": "A last name"}, explain=True)
        assert resp["index"]["type"] == "json"

    def test_with_and(self):
        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            },
            explain=True)
        assert resp["index"]["type"] == "json"

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_with_text(self):
        resp = self.db.find(
            {
                "$text": "Stephanie",
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            },
            explain=True)
        assert resp["index"]["type"] == "text"

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_no_view_index(self):
        resp = self.db.find({"name.first": "Ohai!"}, explain=True)
        assert resp["index"]["type"] == "text"

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_with_or(self):
        resp = self.db.find(
            {
                "$or": [{
                    "name.first": "Stephanie"
                }, {
                    "name.last": "This doesn't have to match anything."
                }]
            },
            explain=True)
        assert resp["index"]["type"] == "text"

    def test_use_most_columns(self):
        # ddoc id for the age index
        ddocid = "_design/ad3d537c03cd7c6a43cf8dff66ef70ea54c2b40f"
        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "Something or other",
                "age": {
                    "$gt": 1
                }
            },
            explain=True)
        assert resp["index"]["ddoc"] != "_design/" + ddocid

        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "Something or other",
                "age": {
                    "$gt": 1
                }
            },
            use_index=ddocid,
            explain=True)
        assert resp["index"]["ddoc"] == ddocid

    # This doc will not be saved given the new ddoc validation code
    # in couch_mrview
    def test_manual_bad_view_idx01(self):
        design_doc = {
            "_id": "_design/bad_view_index",
            "language": "query",
            "views": {
                "queryidx1": {
                    "map": {
                        "fields": {
                            "age": "asc"
                        }
                    },
                    "reduce": "_count",
                    "options": {
                        "def": {
                            "fields": [{
                                "age": "asc"
                            }]
                        },
                        "w": 2
                    }
                }
            },
            "views": {
                "views001": {
                    "map":
                    "function(employee){if(employee.training)" +
                    "{emit(employee.number, employee.training);}}"
                }
            }
        }
        with self.assertRaises(KeyError):
            self.db.save_doc(design_doc)

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_manual_bad_text_idx(self):
        design_doc = {
            "_id": "_design/bad_text_index",
            "language": "query",
            "indexes": {
                "text_index": {
                    "default_analyzer": "keyword",
                    "default_field": {},
                    "selector": {},
                    "fields": "all_fields",
                    "analyzer": {
                        "name": "perfield",
                        "default": "keyword",
                        "fields": {
                            "$default": "standard"
                        }
                    }
                }
            },
            "indexes": {
                "st_index": {
                    "analyzer":
                    "standard",
                    "index":
                    "function(doc){\n index(\"st_index\", doc.geometry);\n}"
                }
            }
        }
        self.db.save_doc(design_doc)
        docs = self.db.find({"age": 48})
        assert len(docs) == 1
        assert docs[0]["name"]["first"] == "Stephanie"
        assert docs[0]["age"] == 48
# 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.

import mango
import limit_docs
import unittest


@unittest.skipUnless(mango.has_text_service(), "requires text service")
class LimitTests(mango.LimitDocsTextTests):
    def test_limit_field(self):
        q = {"$or": [{"user_id": {"$lt": 10}}, {"filtered_array.[]": 1}]}
        docs = self.db.find(q, limit=10)
        assert len(docs) == 8
        for d in docs:
            assert d["user_id"] < 10

    def test_limit_field2(self):
        q = {"$or": [{"user_id": {"$lt": 20}}, {"filtered_array.[]": 1}]}
        docs = self.db.find(q, limit=10)
        assert len(docs) == 10
        for d in docs:
            assert d["user_id"] < 20
Beispiel #20
0
class IndexSelectionTests(mango.UserDocsTests):
    @classmethod
    def setUpClass(klass):
        super(IndexSelectionTests, klass).setUpClass()
        if mango.has_text_service():
            user_docs.add_text_indexes(klass.db, {})

    def test_basic(self):
        resp = self.db.find({"age": 123}, explain=True)
        self.assertEqual(resp["index"]["type"], "json")

    def test_with_and(self):
        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            },
            explain=True)
        self.assertEqual(resp["index"]["type"], "json")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_with_text(self):
        resp = self.db.find(
            {
                "$text": "Stephanie",
                "name.first": "Stephanie",
                "name.last": "This doesn't have to match anything."
            },
            explain=True)
        self.assertEqual(resp["index"]["type"], "text")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_no_view_index(self):
        resp = self.db.find({"name.first": "Ohai!"}, explain=True)
        self.assertEqual(resp["index"]["type"], "text")

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_with_or(self):
        resp = self.db.find(
            {
                "$or": [{
                    "name.first": "Stephanie"
                }, {
                    "name.last": "This doesn't have to match anything."
                }]
            },
            explain=True)
        self.assertEqual(resp["index"]["type"], "text")

    def test_use_most_columns(self):
        # ddoc id for the age index
        ddocid = "_design/ad3d537c03cd7c6a43cf8dff66ef70ea54c2b40f"
        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "Something or other",
                "age": {
                    "$gt": 1
                }
            },
            explain=True)
        self.assertNotEqual(resp["index"]["ddoc"], "_design/" + ddocid)

        resp = self.db.find(
            {
                "name.first": "Stephanie",
                "name.last": "Something or other",
                "age": {
                    "$gt": 1
                }
            },
            use_index=ddocid,
            explain=True)
        self.assertEqual(resp["index"]["ddoc"], ddocid)

    def test_no_valid_sort_index(self):
        try:
            self.db.find({"_id": {
                "$gt": None
            }},
                         sort=["name"],
                         return_raw=True)
        except Exception as e:
            self.assertEqual(e.response.status_code, 400)
        else:
            raise AssertionError("bad find")

    def test_invalid_use_index(self):
        # ddoc id for the age index
        ddocid = "_design/ad3d537c03cd7c6a43cf8dff66ef70ea54c2b40f"
        try:
            self.db.find({}, use_index=ddocid)
        except Exception as e:
            self.assertEqual(e.response.status_code, 400)
        else:
            raise AssertionError("bad find")

    def test_uses_all_docs_when_fields_do_not_match_selector(self):
        # index exists on ["company", "manager"] but not ["company"]
        # so we should fall back to all docs (so we include docs
        # with no "manager" field)
        selector = {"company": "Pharmex"}
        docs = self.db.find(selector)
        self.assertEqual(len(docs), 1)
        self.assertEqual(docs[0]["company"], "Pharmex")
        self.assertNotIn("manager", docs[0])

        resp_explain = self.db.find(selector, explain=True)
        self.assertEqual(resp_explain["index"]["type"], "special")

    def test_uses_all_docs_when_selector_doesnt_require_fields_to_exist(self):
        # as in test above, use a selector that doesn't overlap with the index
        # due to an explicit exists clause
        selector = {"company": "Pharmex", "manager": {"$exists": False}}
        docs = self.db.find(selector)
        self.assertEqual(len(docs), 1)
        self.assertEqual(docs[0]["company"], "Pharmex")
        self.assertNotIn("manager", docs[0])

        resp_explain = self.db.find(selector, explain=True)
        self.assertEqual(resp_explain["index"]["type"], "special")

    def test_uses_index_when_no_range_or_equals(self):
        # index on ["manager"] should be valid because
        # selector requires "manager" to exist. The
        # selector doesn't narrow the keyrange so it's
        # a full index scan
        selector = {"manager": {"$exists": True}}
        docs = self.db.find(selector)
        self.assertEqual(len(docs), 14)

        resp_explain = self.db.find(selector, explain=True)
        self.assertEqual(resp_explain["index"]["type"], "json")

    def test_reject_use_index_invalid_fields(self):
        # index on ["company","manager"] which should not be valid
        ddocid = "_design/a0c425a60cf3c3c09e3c537c9ef20059dcef9198"
        selector = {"company": "Pharmex"}
        try:
            self.db.find(selector, use_index=ddocid)
        except Exception as e:
            self.assertEqual(e.response.status_code, 400)
        else:
            raise AssertionError("did not reject bad use_index")

    def test_reject_use_index_sort_order(self):
        # index on ["company","manager"] which should not be valid
        ddocid = "_design/a0c425a60cf3c3c09e3c537c9ef20059dcef9198"
        selector = {"company": {"$gt": None}, "manager": {"$gt": None}}
        try:
            self.db.find(selector,
                         use_index=ddocid,
                         sort=[{
                             "manager": "desc"
                         }])
        except Exception as e:
            self.assertEqual(e.response.status_code, 400)
        else:
            raise AssertionError("did not reject bad use_index")

    # This doc will not be saved given the new ddoc validation code
    # in couch_mrview
    def test_manual_bad_view_idx01(self):
        design_doc = {
            "_id": "_design/bad_view_index",
            "language": "query",
            "views": {
                "queryidx1": {
                    "map": {
                        "fields": {
                            "age": "asc"
                        }
                    },
                    "reduce": "_count",
                    "options": {
                        "def": {
                            "fields": [{
                                "age": "asc"
                            }]
                        },
                        "w": 2
                    }
                }
            },
            "views": {
                "views001": {
                    "map":
                    "function(employee){if(employee.training)" +
                    "{emit(employee.number, employee.training);}}"
                }
            }
        }
        with self.assertRaises(KeyError):
            self.db.save_doc(design_doc)

    @unittest.skipUnless(mango.has_text_service(), "requires text service")
    def test_manual_bad_text_idx(self):
        design_doc = {
            "_id": "_design/bad_text_index",
            "language": "query",
            "indexes": {
                "text_index": {
                    "default_analyzer": "keyword",
                    "default_field": {},
                    "selector": {},
                    "fields": "all_fields",
                    "analyzer": {
                        "name": "perfield",
                        "default": "keyword",
                        "fields": {
                            "$default": "standard"
                        }
                    }
                }
            },
            "indexes": {
                "st_index": {
                    "analyzer":
                    "standard",
                    "index":
                    "function(doc){\n index(\"st_index\", doc.geometry);\n}"
                }
            }
        }
        self.db.save_doc(design_doc)
        docs = self.db.find({"age": 48})
        self.assertEqual(len(docs), 1)
        self.assertEqual(docs[0]["name"]["first"], "Stephanie")
        self.assertEqual(docs[0]["age"], 48)