Exemplo n.º 1
0
TEST(FTSSpec, Extra3) {
    BSONObj user = BSON("key" << BSON("x" << 1 << "data"
                                      << "text"));
    BSONObj fixed = assertGet(FTSSpec::fixSpec(user));

    ASSERT_BSONOBJ_EQ(BSON("x" << 1 << "_fts"
                           << "text"
                           << "_ftsx"
                           << 1),
                      fixed["key"].Obj());
    ASSERT_BSONOBJ_EQ(BSON("data" << 1), fixed["weights"].Obj());

    BSONObj fixed2 = assertGet(FTSSpec::fixSpec(fixed));
    ASSERT_BSONOBJ_EQ(fixed, fixed2);

    FTSSpec spec(fixed);
    ASSERT_EQUALS(1U, spec.numExtraBefore());
    ASSERT_EQUALS(StringData("x"), spec.extraBefore(0));
    ASSERT_EQUALS(0U, spec.numExtraAfter());

    BSONObj prefix;

    ASSERT(spec.getIndexPrefix(BSON("x" << 2), &prefix).isOK());
    ASSERT_BSONOBJ_EQ(BSON("x" << 2), prefix);

    ASSERT(spec.getIndexPrefix(BSON("x" << 3 << "y" << 4), &prefix).isOK());
    ASSERT_BSONOBJ_EQ(BSON("x" << 3), prefix);

    ASSERT(!spec.getIndexPrefix(BSON("x" << BSON("$gt" << 5)), &prefix).isOK());
    ASSERT(!spec.getIndexPrefix(BSON("y" << 4), &prefix).isOK());
    ASSERT(!spec.getIndexPrefix(BSONObj(), &prefix).isOK());
}
Exemplo n.º 2
0
TEST_F(UpdateArrayNodeTest, UpdateIsAppliedToAllMatchingElements) {
    auto update = fromjson("{$set: {'a.$[i]': 2}}");
    auto arrayFilter = fromjson("{i: 0}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
    auto parsedFilter = assertGet(MatchExpressionParser::parse(arrayFilter, expCtx));
    arrayFilters["i"] = assertGet(ExpressionWithPlaceholder::make(std::move(parsedFilter)));
    std::set<std::string> foundIdentifiers;
    UpdateObjectNode root;
    ASSERT_OK(UpdateObjectNode::parseAndMerge(&root,
                                              modifiertable::ModifierType::MOD_SET,
                                              update["$set"]["a.$[i]"],
                                              expCtx,
                                              arrayFilters,
                                              foundIdentifiers));

    mutablebson::Document doc(fromjson("{a: [0, 1, 0]}"));
    addIndexedPath("a");
    auto result = root.apply(getApplyParams(doc.root()));
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_FALSE(result.noop);
    ASSERT_EQUALS(fromjson("{a: [2, 1, 2]}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$set: {a: [2, 1, 2]}}"), getLogDoc());
    ASSERT_EQUALS("{a.0, a.2}", getModifiedPaths());
}
/**
 * Test the way cache entries are added (either "active" or "inactive") to the plan cache.
 */
TEST_F(QueryStageCachedPlan, QueryStageCachedPlanAddsActiveCacheEntries) {
    AutoGetCollectionForReadCommand ctx(&_opCtx, nss);
    Collection* collection = ctx.getCollection();
    ASSERT(collection);

    // Never run - just used as a key for the cache's get() functions, since all of the other
    // CanonicalQueries created in this test will have this shape.
    const auto shapeCq =
        canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 123}, b: {$gte: 123}}"));

    // Query can be answered by either index on "a" or index on "b".
    const auto noResultsCq =
        canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 11}, b: {$gte: 11}}"));

    // We shouldn't have anything in the plan cache for this shape yet.
    PlanCache* cache = collection->infoCache()->getPlanCache();
    ASSERT(cache);
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kNotPresent);

    // Run the CachedPlanStage with a long-running child plan. Replanning should be
    // triggered and an inactive entry will be added.
    forceReplanning(collection, noResultsCq.get());

    // Check for an inactive cache entry.
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive);

    // The works should be 1 for the entry since the query we ran should not have any results.
    auto entry = assertGet(cache->getEntry(*shapeCq));
    size_t works = 1U;
    ASSERT_EQ(entry->works, works);

    const size_t kExpectedNumWorks = 10;
    for (int i = 0; i < std::ceil(std::log(kExpectedNumWorks) / std::log(2)); ++i) {
        works *= 2;
        // Run another query of the same shape, which is less selective, and therefore takes
        // longer).
        auto someResultsCq =
            canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 1}, b: {$gte: 0}}"));
        forceReplanning(collection, someResultsCq.get());

        ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive);
        // The works on the cache entry should have doubled.
        entry = assertGet(cache->getEntry(*shapeCq));
        ASSERT_EQ(entry->works, works);
    }

    // Run another query which takes less time, and be sure an active entry is created.
    auto fewResultsCq =
        canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 6}, b: {$gte: 0}}"));
    forceReplanning(collection, fewResultsCq.get());

    // Now there should be an active cache entry.
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentActive);
    entry = assertGet(cache->getEntry(*shapeCq));
    // This will query will match {a: 6} through {a:9} (4 works), plus one for EOF = 5 works.
    ASSERT_EQ(entry->works, 5U);
}
TEST_F(QueryStageCachedPlan, DeactivatesEntriesOnReplan) {
    AutoGetCollectionForReadCommand ctx(&_opCtx, nss);
    Collection* collection = ctx.getCollection();
    ASSERT(collection);

    // Never run - just used as a key for the cache's get() functions, since all of the other
    // CanonicalQueries created in this test will have this shape.
    const auto shapeCq =
        canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 123}, b: {$gte: 123}}"));

    // Query can be answered by either index on "a" or index on "b".
    const auto noResultsCq =
        canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 11}, b: {$gte: 11}}"));

    // We shouldn't have anything in the plan cache for this shape yet.
    PlanCache* cache = collection->infoCache()->getPlanCache();
    ASSERT(cache);
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kNotPresent);

    // Run the CachedPlanStage with a long-running child plan. Replanning should be
    // triggered and an inactive entry will be added.
    forceReplanning(collection, noResultsCq.get());

    // Check for an inactive cache entry.
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive);

    // Run the plan again, to create an active entry.
    forceReplanning(collection, noResultsCq.get());

    // The works should be 1 for the entry since the query we ran should not have any results.
    ASSERT_EQ(cache->get(*noResultsCq.get()).state, PlanCache::CacheEntryState::kPresentActive);
    auto entry = assertGet(cache->getEntry(*shapeCq));
    size_t works = 1U;
    ASSERT_EQ(entry->works, works);

    // Run another query which takes long enough to evict the active cache entry. The current
    // cache entry's works value is a very low number. When replanning is triggered, the cache
    // entry will be deactivated, but the new plan will not overwrite it, since the new plan will
    // have a higher works. Therefore, we will be left in an inactive entry which has had its works
    // value doubled from 1 to 2.
    auto highWorksCq =
        canonicalQueryFromFilterObj(opCtx(), nss, fromjson("{a: {$gte: 0}, b: {$gte:0}}"));
    forceReplanning(collection, highWorksCq.get());
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentInactive);
    ASSERT_EQ(assertGet(cache->getEntry(*shapeCq))->works, 2U);

    // Again, force replanning. This time run the initial query which finds no results. The multi
    // planner will choose a plan with works value lower than the existing inactive
    // entry. Replanning will thus deactivate the existing entry (it's already
    // inactive so this is a noop), then create a new entry with a works value of 1.
    forceReplanning(collection, noResultsCq.get());
    ASSERT_EQ(cache->get(*shapeCq).state, PlanCache::CacheEntryState::kPresentActive);
    ASSERT_EQ(assertGet(cache->getEntry(*shapeCq))->works, 1U);
}
Exemplo n.º 5
0
TEST(FTSSpec, Extra2) {
    BSONObj user = BSON("key" << BSON("data"
                                      << "text"
                                      << "x"
                                      << 1));
    BSONObj fixed = assertGet(FTSSpec::fixSpec(user));
    FTSSpec spec(fixed);
    ASSERT_EQUALS(0U, spec.numExtraBefore());
    ASSERT_EQUALS(1U, spec.numExtraAfter());
    ASSERT_EQUALS(StringData("x"), spec.extraAfter(0));

    BSONObj fixed2 = assertGet(FTSSpec::fixSpec(fixed));
    ASSERT_BSONOBJ_EQ(fixed, fixed2);
}
Exemplo n.º 6
0
/**
 * Assert that fixSpec() accepts the provided text index spec.
 */
void assertFixSuccess(const std::string& s) {
    BSONObj user = fromjson(s);

    try {
        // fixSpec() should not throw on a valid spec.
        BSONObj fixed = assertGet(FTSSpec::fixSpec(user));

        // fixSpec() on an already-fixed spec shouldn't change it.
        BSONObj fixed2 = assertGet(FTSSpec::fixSpec(fixed));
        ASSERT_BSONOBJ_EQ(fixed, fixed2);
    } catch (UserException&) {
        ASSERT(false);
    }
}
Exemplo n.º 7
0
TEST(FTSSpec, ScoreMultipleField1) {
    BSONObj user = BSON("key" << BSON("title"
                                      << "text"
                                      << "text"
                                      << "text")
                        << "weights"
                        << BSON("title" << 10));

    FTSSpec spec(assertGet(FTSSpec::fixSpec(user)));

    TermFrequencyMap m;
    spec.scoreDocument(BSON("title"
                            << "cat sat run"
                            << "text"
                            << "cat book"),
                       &m);

    ASSERT_EQUALS(4U, m.size());
    ASSERT_EQUALS(m["sat"], m["run"]);
    ASSERT(m["sat"] > 0);

    ASSERT(m["cat"] > m["sat"]);
    ASSERT(m["cat"] > m["book"]);
    ASSERT(m["book"] > 0);
    ASSERT(m["book"] < m["sat"]);
}
Exemplo n.º 8
0
TEST(QueryRequestTest, DefaultQueryParametersCorrect) {
    BSONObj cmdObj = fromjson("{find: 'testns'}");

    const NamespaceString nss("test.testns");
    std::unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, false)));

    ASSERT_FALSE(qr->getSkip());
    ASSERT_FALSE(qr->getLimit());

    ASSERT_EQUALS(true, qr->wantMore());
    ASSERT_FALSE(qr->getNToReturn());
    ASSERT_EQUALS(false, qr->isExplain());
    ASSERT_EQUALS(0, qr->getMaxTimeMS());
    ASSERT_EQUALS(false, qr->returnKey());
    ASSERT_EQUALS(false, qr->showRecordId());
    ASSERT_EQUALS(false, qr->hasReadPref());
    ASSERT_EQUALS(false, qr->isTailable());
    ASSERT_EQUALS(false, qr->isSlaveOk());
    ASSERT_EQUALS(false, qr->isOplogReplay());
    ASSERT_EQUALS(false, qr->isNoCursorTimeout());
    ASSERT_EQUALS(false, qr->isTailableAndAwaitData());
    ASSERT_EQUALS(false, qr->isExhaust());
    ASSERT_EQUALS(false, qr->isAllowPartialResults());
}
Exemplo n.º 9
0
// Multi-language test_6: test wildcard spec with override
TEST(FTSSpec, NestedLanguages_WildcardOverride) {
    BSONObj indexSpec = BSON("key" << BSON("$**"
                                           << "text")
                             << "weights"
                             << BSON("d.e.f" << 20));
    FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
    TermFrequencyMap tfm;

    BSONObj obj = fromjson(
                      "{ language : \"english\","
                      "  b : \"walking\","
                      "  c : { e: \"walked\" },"
                      "  d : "
                      "  { language : \"danish\","
                      "    e :"
                      "    [ { f : \"foredrag\" },"
                      "      { f : \"foredragsholder\" },"
                      "      { f : \"lector\" } ]"
                      "  }"
                      "}");

    spec.scoreDocument(obj, &tfm);

    set<string> hits;
    hits.insert("foredrag");
    hits.insert("foredragshold");
    hits.insert("lector");
    hits.insert("walk");

    for (TermFrequencyMap::const_iterator i = tfm.begin(); i != tfm.end(); ++i) {
        string term = i->first;
        ASSERT_EQUALS(1U, hits.count(term));
    }
}
Exemplo n.º 10
0
TEST(QueryRequestTest, ParseFromLegacyQuery) {
    const auto kSkip = 1;
    const auto kNToReturn = 2;

    BSONObj queryObj = fromjson(R"({
            query: {query: 1},
            orderby: {sort: 1},
            $hint: {hint: 1},
            $explain: false,
            $min: {x: 'min'},
            $max: {x: 'max'}
         })");
    const NamespaceString nss("test.testns");
    unique_ptr<QueryRequest> qr(assertGet(QueryRequest::fromLegacyQuery(
        nss, queryObj, BSON("proj" << 1), kSkip, kNToReturn, QueryOption_Exhaust)));

    ASSERT_EQ(qr->nss(), nss);
    ASSERT_BSONOBJ_EQ(qr->getFilter(), fromjson("{query: 1}"));
    ASSERT_BSONOBJ_EQ(qr->getProj(), fromjson("{proj: 1}"));
    ASSERT_BSONOBJ_EQ(qr->getSort(), fromjson("{sort: 1}"));
    ASSERT_BSONOBJ_EQ(qr->getHint(), fromjson("{hint: 1}"));
    ASSERT_BSONOBJ_EQ(qr->getMin(), fromjson("{x: 'min'}"));
    ASSERT_BSONOBJ_EQ(qr->getMax(), fromjson("{x: 'max'}"));
    ASSERT_EQ(qr->getSkip(), boost::optional<long long>(kSkip));
    ASSERT_EQ(qr->getNToReturn(), boost::optional<long long>(kNToReturn));
    ASSERT_EQ(qr->wantMore(), true);
    ASSERT_EQ(qr->isExplain(), false);
    ASSERT_EQ(qr->isSlaveOk(), false);
    ASSERT_EQ(qr->isOplogReplay(), false);
    ASSERT_EQ(qr->isNoCursorTimeout(), false);
    ASSERT_EQ(qr->isTailable(), false);
    ASSERT_EQ(qr->isExhaust(), true);
    ASSERT_EQ(qr->isAllowPartialResults(), false);
    ASSERT_EQ(qr->getOptions(), QueryOption_Exhaust);
}
Exemplo n.º 11
0
TEST(FTSSpec, Extra1) {
    BSONObj user = BSON("key" << BSON("data"
                                      << "text"));
    FTSSpec spec(assertGet(FTSSpec::fixSpec(user)));
    ASSERT_EQUALS(0U, spec.numExtraBefore());
    ASSERT_EQUALS(0U, spec.numExtraAfter());
}
Exemplo n.º 12
0
TEST(QueryRequestTest, ParseFromCommandAllFlagsTrue) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "tailable: true,"
        "oplogReplay: true,"
        "noCursorTimeout: true,"
        "awaitData: true,"
        "allowPartialResults: true,"
        "readOnce: true,"
        "allowSpeculativeMajorityRead: true}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    // Test that all the flags got set to true.
    ASSERT(qr->isTailable());
    ASSERT(!qr->isSlaveOk());
    ASSERT(qr->isOplogReplay());
    ASSERT(qr->isNoCursorTimeout());
    ASSERT(qr->isTailableAndAwaitData());
    ASSERT(qr->isAllowPartialResults());
    ASSERT(qr->isReadOnce());
    ASSERT(qr->allowSpeculativeMajorityRead());
}
Exemplo n.º 13
0
// Multi-language test_4: test pruning
TEST(FTSSpec, NestedLanguages_PathPruning) {
    BSONObj indexSpec = BSON("key" << BSON("a.b.c"
                                           << "text"));
    FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
    TermFrequencyMap tfm;

    BSONObj obj = fromjson(
                      "{ language : \"english\","
                      "  a : "
                      "  { language : \"danish\","
                      "    bc : \"foo\","
                      "    b : { d: \"bar\" },"
                      "    b :"
                      "    [ { c : \"foredrag\" },"
                      "      { c : \"foredragsholder\" },"
                      "      { c : \"lector\" } ]"
                      "  }"
                      "}");

    spec.scoreDocument(obj, &tfm);

    set<string> hits;
    hits.insert("foredrag");
    hits.insert("foredragshold");
    hits.insert("lector");

    for (TermFrequencyMap::const_iterator i = tfm.begin(); i != tfm.end(); ++i) {
        string term = i->first;
        ASSERT_EQUALS(1U, hits.count(term));
    }
}
Exemplo n.º 14
0
// Multi-language test_1: test independent stemming per sub-document
TEST(FTSSpec, NestedLanguages_PerArrayItemStemming) {
    BSONObj indexSpec = BSON("key" << BSON("a.b.c"
                                           << "text"));
    FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
    TermFrequencyMap tfm;

    BSONObj obj = fromjson(
                      "{ a :"
                      "  { b :"
                      "    [ { c : \"walked\", language : \"english\" },"
                      "      { c : \"camminato\", language : \"italian\" },"
                      "      { c : \"ging\", language : \"german\" } ]"
                      "   }"
                      " }");

    spec.scoreDocument(obj, &tfm);

    set<string> hits;
    hits.insert("walk");
    hits.insert("cammin");
    hits.insert("ging");

    for (TermFrequencyMap::const_iterator i = tfm.begin(); i != tfm.end(); ++i) {
        string term = i->first;
        ASSERT_EQUALS(1U, hits.count(term));
    }
}
Exemplo n.º 15
0
TEST(QueryRequestTest, ParseFromCommandReadOnceDefaultsToFalse) {
    BSONObj cmdObj = fromjson("{find: 'testns'}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));
    ASSERT(!qr->isReadOnce());
}
Exemplo n.º 16
0
TEST(QueryRequestTest, ParseCommandIsFromFindCommand) {
    BSONObj cmdObj = fromjson("{find: 'testns'}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    ASSERT_FALSE(qr->getNToReturn());
}
Exemplo n.º 17
0
TEST(QueryRequestTest, ParseFromLegacyStringMetaOpComment) {
    BSONObj queryObj = fromjson(
        "{$query: {a: 1},"
        "$comment: 'ParseFromLegacyStringMetaOpComment'}");
    const NamespaceString nss("test.testns");
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::fromLegacyQuery(nss, queryObj, BSONObj(), 0, 0, 0)));

    ASSERT_EQ(qr->getComment(), "ParseFromLegacyStringMetaOpComment");
    ASSERT_BSONOBJ_EQ(qr->getFilter(), fromjson("{a: 1}"));
}
Exemplo n.º 18
0
TEST(FTSSpec, NestedArraysPos1) {
    BSONObj user = BSON("key" << BSON("a.b"
                                      << "text"));
    FTSSpec spec(assertGet(FTSSpec::fixSpec(user)));

    // The following document matches {"a.b": {$type: 2}}, so "term" should be indexed.
    BSONObj obj = fromjson("{a: [{b: ['term']}]}");  // indirectly nested arrays
    TermFrequencyMap m;
    spec.scoreDocument(obj, &m);
    ASSERT_EQUALS(1U, m.size());
}
Exemplo n.º 19
0
TEST(FTSSpec, NestedArraysPos2) {
    BSONObj user = BSON("key" << BSON("$**"
                                      << "text"));
    FTSSpec spec(assertGet(FTSSpec::fixSpec(user)));

    // The wildcard spec implies a full recursive traversal, so "term" should be indexed.
    BSONObj obj = fromjson("{a: {b: [['term']]}}");  // directly nested arrays
    TermFrequencyMap m;
    spec.scoreDocument(obj, &m);
    ASSERT_EQUALS(1U, m.size());
}
Exemplo n.º 20
0
/** Test differences across textIndexVersion values in handling of nested arrays. */
TEST(FTSSpec, TextIndexLegacyNestedArrays) {
    BSONObj obj = fromjson("{a: [{b: ['hello']}]}");

    // textIndexVersion=1 FTSSpec objects do not index nested arrays.
    {
        BSONObj indexSpec = fromjson("{key: {'a.b': 'text'}, textIndexVersion: 1}");
        FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
        TermFrequencyMap tfm;
        spec.scoreDocument(obj, &tfm);
        ASSERT_EQUALS(tfm.size(), 0U);
    }

    // textIndexVersion=2 FTSSpec objects do index nested arrays.
    {
        BSONObj indexSpec = fromjson("{key: {'a.b': 'text'}, textIndexVersion: 2}");
        FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
        TermFrequencyMap tfm;
        spec.scoreDocument(obj, &tfm);
        ASSERT_EQUALS(tfm.size(), 1U);
    }
}
Exemplo n.º 21
0
TEST(QueryRequestTest, ParseFromLegacyObjMetaOpComment) {
    BSONObj queryObj = fromjson(
        "{$query: {a: 1},"
        "$comment: {b: 2, c: {d: 'ParseFromLegacyObjMetaOpComment'}}}");
    const NamespaceString nss("test.testns");
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::fromLegacyQuery(nss, queryObj, BSONObj(), 0, 0, 0)));

    // Ensure that legacy comment meta-operator is parsed to a string comment
    ASSERT_EQ(qr->getComment(), "{ b: 2, c: { d: \"ParseFromLegacyObjMetaOpComment\" } }");
    ASSERT_BSONOBJ_EQ(qr->getFilter(), fromjson("{a: 1}"));
}
Exemplo n.º 22
0
TEST(QueryRequestTest, ParseFromCommandBatchSizeZero) {
    BSONObj cmdObj = fromjson("{find: 'testns', batchSize: 0}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    ASSERT(qr->getBatchSize());
    ASSERT_EQ(0, *qr->getBatchSize());

    ASSERT(!qr->getLimit());
}
Exemplo n.º 23
0
TEST(QueryRequestTest, ParseFromCommandLimitIsZero) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "limit: 0,"
        "filter: {a: 3}}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));
    ASSERT_BSONOBJ_EQ(BSON("a" << 3), qr->getFilter());
    ASSERT_FALSE(qr->getLimit());
}
Exemplo n.º 24
0
TEST(QueryRequestTest, ParseFromCommandLargeSkip) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "filter: {a: 1},"
        "skip: 8000000000}");  // 8 * 1000 * 1000 * 1000
    const NamespaceString nss("test.testns");
    const bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    ASSERT_EQUALS(8LL * 1000 * 1000 * 1000, *qr->getSkip());
}
Exemplo n.º 25
0
/** Test differences across textIndexVersion values in handling of language annotations. */
TEST(FTSSpec, TextIndexLegacyLanguageRecognition) {
    BSONObj obj = fromjson("{a: 'the', language: 'EN'}");

    // textIndexVersion=1 FTSSpec objects treat two-letter language annotations as "none"
    // for purposes of stopword processing.
    {
        BSONObj indexSpec = fromjson("{key: {'a': 'text'}, textIndexVersion: 1}");
        FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
        TermFrequencyMap tfm;
        spec.scoreDocument(obj, &tfm);
        ASSERT_EQUALS(tfm.size(), 1U);  // "the" not recognized as stopword
    }

    // textIndexVersion=2 FTSSpec objects recognize two-letter codes.
    {
        BSONObj indexSpec = fromjson("{key: {'a': 'text'}, textIndexVersion: 2}");
        FTSSpec spec(assertGet(FTSSpec::fixSpec(indexSpec)));
        TermFrequencyMap tfm;
        spec.scoreDocument(obj, &tfm);
        ASSERT_EQUALS(tfm.size(), 0U);  // "the" recognized as stopword
    }
}
Exemplo n.º 26
0
TEST(FTSSpec, ScoreMultipleField2) {
    // Test where one indexed field is a parent component of another indexed field.
    BSONObj user = BSON("key" << BSON("a"
                                      << "text"
                                      << "a.b"
                                      << "text"));

    FTSSpec spec(assertGet(FTSSpec::fixSpec(user)));

    TermFrequencyMap m;
    spec.scoreDocument(BSON("a" << BSON("b"
                                        << "term")),
                       &m);
    ASSERT_EQUALS(1U, m.size());
}
Exemplo n.º 27
0
TEST(QueryRequestTest, ParseFromCommandWithOptions) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "filter: {a: 3},"
        "sort: {a: 1},"
        "projection: {_id: 0, a: 1},"
        "showRecordId: true}}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    // Make sure the values from the command BSON are reflected in the QR.
    ASSERT(qr->showRecordId());
}
Exemplo n.º 28
0
TEST(QueryRequestTest, ParseFromCommandHintAsString) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "filter:  {a: 1},"
        "hint: 'foo_1'}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    BSONObj hintObj = qr->getHint();
    ASSERT_BSONOBJ_EQ(BSON("$hint"
                           << "foo_1"),
                      hintObj);
}
Exemplo n.º 29
0
TEST(QueryRequestTest, ParseFromCommandCommentWithValidMinMax) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "comment: 'the comment',"
        "min: {a: 1},"
        "max: {a: 2}}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));

    ASSERT_EQUALS("the comment", qr->getComment());
    BSONObj expectedMin = BSON("a" << 1);
    ASSERT_EQUALS(0, expectedMin.woCompare(qr->getMin()));
    BSONObj expectedMax = BSON("a" << 2);
    ASSERT_EQUALS(0, expectedMax.woCompare(qr->getMax()));
}
Exemplo n.º 30
0
TEST(QueryRequestTest, AsFindCommandAllNonOptionFields) {
    BSONObj cmdObj = fromjson(
        "{find: 'testns',"
        "filter: {a: 1},"
        "projection: {c: 1},"
        "sort: {b: 1},"
        "hint: {d: 1},"
        "readConcern: {e: 1},"
        "collation: {f: 1},"
        "skip: 5,"
        "limit: 3,"
        "batchSize: 90,"
        "singleBatch: true}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    unique_ptr<QueryRequest> qr(
        assertGet(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain)));
    ASSERT_BSONOBJ_EQ(cmdObj, qr->asFindCommand());
}