diff options
Diffstat (limited to 'src/mango/test/05-index-selection-test.py')
-rw-r--r-- | src/mango/test/05-index-selection-test.py | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/src/mango/test/05-index-selection-test.py b/src/mango/test/05-index-selection-test.py deleted file mode 100644 index cb4d32986..000000000 --- a/src/mango/test/05-index-selection-test.py +++ /dev/null @@ -1,336 +0,0 @@ -# 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. - -import mango -import user_docs -import unittest - - -class IndexSelectionTests: - 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") - - def test_with_nested_and(self): - resp = self.db.find( - {"name.first": {"$gt": "a", "$lt": "z"}, "name.last": "Foo"}, explain=True - ) - self.assertEqual(resp["index"]["type"], "json") - - def test_with_or(self): - ddocid = "_design/company_and_manager" - - resp = self.db.find( - { - "company": {"$gt": "a", "$lt": "z"}, - "$or": [{"manager": "Foo"}, {"manager": "Bar"}], - }, - explain=True, - ) - self.assertEqual(resp["index"]["ddoc"], ddocid) - - def test_use_most_columns(self): - ddocid = "_design/age" - resp = self.db.find( - { - "name.first": "Stephanie", - "name.last": "Something or other", - "age": {"$gt": 1}, - }, - explain=True, - ) - self.assertNotEqual(resp["index"]["ddoc"], 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/age" - r = self.db.find({}, use_index=ddocid, return_raw=True) - self.assertEqual( - r["warning"].split("\n")[0].lower(), - "{0} was not used because it does not contain a valid index for this query.".format( - ddocid - ), - ) - - 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): - ddocid = "_design/company_and_manager" - selector = {"company": "Pharmex"} - r = self.db.find(selector, use_index=ddocid, return_raw=True) - self.assertEqual( - r["warning"].split("\n")[0].lower(), - "{0} was not used because it does not contain a valid index for this query.".format( - ddocid - ), - ) - - # should still return a correct result - for d in r["docs"]: - self.assertEqual(d["company"], "Pharmex") - - def test_reject_use_index_ddoc_and_name_invalid_fields(self): - ddocid = "_design/company_and_manager" - name = "company_and_manager" - selector = {"company": "Pharmex"} - - resp = self.db.find(selector, use_index=[ddocid, name], return_raw=True) - self.assertEqual( - resp["warning"].split("\n")[0].lower(), - "{0}, {1} was not used because it is not a valid index for this query.".format( - ddocid, name - ), - ) - - # should still return a correct result - for d in resp["docs"]: - self.assertEqual(d["company"], "Pharmex") - - def test_reject_use_index_sort_order(self): - # index on ["company","manager"] which should not be valid - # and there is no valid fallback (i.e. an index on ["company"]) - ddocid = "_design/company_and_manager" - selector = {"company": {"$gt": None}} - try: - self.db.find(selector, use_index=ddocid, sort=[{"company": "desc"}]) - except Exception as e: - self.assertEqual(e.response.status_code, 400) - else: - raise AssertionError("did not reject bad use_index") - - def test_use_index_fallback_if_valid_sort(self): - ddocid_valid = "_design/fallbackfoo" - ddocid_invalid = "_design/fallbackfoobar" - self.db.create_index(fields=["foo"], ddoc=ddocid_invalid) - self.db.create_index(fields=["foo", "bar"], ddoc=ddocid_valid) - selector = {"foo": {"$gt": None}} - - resp_explain = self.db.find( - selector, sort=["foo", "bar"], use_index=ddocid_invalid, explain=True - ) - self.assertEqual(resp_explain["index"]["ddoc"], ddocid_valid) - - resp = self.db.find( - selector, sort=["foo", "bar"], use_index=ddocid_invalid, return_raw=True - ) - self.assertEqual( - resp["warning"].split("\n")[0].lower(), - "{0} was not used because it does not contain a valid index for this query.".format( - ddocid_invalid - ), - ) - self.assertEqual(len(resp["docs"]), 0) - - def test_prefer_use_index_over_optimal_index(self): - # index on ["company"] even though index on ["company", "manager"] is better - ddocid_preferred = "_design/testsuboptimal" - self.db.create_index(fields=["baz"], ddoc=ddocid_preferred) - self.db.create_index(fields=["baz", "bar"]) - selector = {"baz": {"$gt": None}, "bar": {"$gt": None}} - resp = self.db.find(selector, use_index=ddocid_preferred, return_raw=True) - self.assertTrue("warning" not in resp) - - resp_explain = self.db.find(selector, use_index=ddocid_preferred, explain=True) - self.assertEqual(resp_explain["index"]["ddoc"], ddocid_preferred) - - # 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) - - def test_explain_sort_reverse(self): - selector = {"manager": {"$gt": None}} - resp_explain = self.db.find( - selector, fields=["manager"], sort=[{"manager": "desc"}], explain=True - ) - self.assertEqual(resp_explain["index"]["type"], "json") - - -class JSONIndexSelectionTests(mango.UserDocsTests, IndexSelectionTests): - @classmethod - def setUpClass(klass): - super(JSONIndexSelectionTests, klass).setUpClass() - - 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") - - -@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") - - def test_no_view_index(self): - resp = self.db.find({"name.first": "Ohai!"}, explain=True) - self.assertEqual(resp["index"]["type"], "text") - - 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_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) - - -@unittest.skipUnless(mango.has_text_service(), "requires text service") -class MultiTextIndexSelectionTests(mango.UserDocsTests): - @classmethod - 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 test_fallback_to_json_with_multi_text(self): - resp = self.db.find( - {"name.first": "A first name", "name.last": "A last name"}, explain=True - ) - self.assertEqual(resp["index"]["type"], "json") - - def test_multi_text_index_is_error(self): - try: - self.db.find({"$text": "a query"}, explain=True) - except Exception as e: - self.assertEqual(e.response.status_code, 400) - - def test_use_index_works(self): - resp = self.db.find({"$text": "a query"}, use_index="foo", explain=True) - self.assertEqual(resp["index"]["ddoc"], "_design/foo") |