本文整理汇总了C++中MatchExpression类的典型用法代码示例。如果您正苦于以下问题:C++ MatchExpression类的具体用法?C++ MatchExpression怎么用?C++ MatchExpression使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了MatchExpression类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: _queryVector
Status AuthzManagerExternalStateMock::_queryVector(
const NamespaceString& collectionName,
const BSONObj& query,
std::vector<BSONObjCollection::iterator>* result) {
StatusWithMatchExpression parseResult = MatchExpressionParser::parse(query);
if (!parseResult.isOK()) {
return parseResult.getStatus();
}
MatchExpression* matcher = parseResult.getValue();
NamespaceDocumentMap::iterator mapIt = _documents.find(collectionName);
if (mapIt == _documents.end())
return Status(ErrorCodes::NoMatchingDocument,
"No collection named " + collectionName.ns());
for (BSONObjCollection::iterator vecIt = mapIt->second.begin();
vecIt != mapIt->second.end();
++vecIt) {
if (matcher->matchesBSON(*vecIt)) {
result->push_back(vecIt);
}
}
return Status::OK();
}
示例2: normalizeTree
// static
MatchExpression* CanonicalQuery::normalizeTree(MatchExpression* root) {
// root->isLogical() is true now. We care about AND, OR, and NOT. NOR currently scares us.
if (MatchExpression::AND == root->matchType() || MatchExpression::OR == root->matchType()) {
// We could have AND of AND of AND. Make sure we clean up our children before merging
// them.
// UNITTEST 11738048
for (size_t i = 0; i < root->getChildVector()->size(); ++i) {
(*root->getChildVector())[i] = normalizeTree(root->getChild(i));
}
// If any of our children are of the same logical operator that we are, we remove the
// child's children and append them to ourselves after we examine all children.
std::vector<MatchExpression*> absorbedChildren;
for (size_t i = 0; i < root->numChildren();) {
MatchExpression* child = root->getChild(i);
if (child->matchType() == root->matchType()) {
// AND of an AND or OR of an OR. Absorb child's children into ourself.
for (size_t j = 0; j < child->numChildren(); ++j) {
absorbedChildren.push_back(child->getChild(j));
}
// TODO(opt): this is possibly n^2-ish
root->getChildVector()->erase(root->getChildVector()->begin() + i);
child->getChildVector()->clear();
// Note that this only works because we cleared the child's children
delete child;
// Don't increment 'i' as the current child 'i' used to be child 'i+1'
} else {
++i;
}
}
root->getChildVector()->insert(
root->getChildVector()->end(), absorbedChildren.begin(), absorbedChildren.end());
// AND of 1 thing is the thing, OR of 1 thing is the thing.
if (1 == root->numChildren()) {
MatchExpression* ret = root->getChild(0);
root->getChildVector()->clear();
delete root;
return ret;
}
} else if (MatchExpression::NOT == root->matchType()) {
// Normalize the rest of the tree hanging off this NOT node.
NotMatchExpression* nme = static_cast<NotMatchExpression*>(root);
MatchExpression* child = nme->releaseChild();
// normalizeTree(...) takes ownership of 'child', and then
// transfers ownership of its return value to 'nme'.
nme->resetChild(normalizeTree(child));
} else if (MatchExpression::ELEM_MATCH_VALUE == root->matchType()) {
// Just normalize our children.
for (size_t i = 0; i < root->getChildVector()->size(); ++i) {
(*root->getChildVector())[i] = normalizeTree(root->getChild(i));
}
}
return root;
}
示例3: TEST
TEST( MatchExpressionParserText, Parse1 ) {
BSONObj query = fromjson( "{$text:{$search:\"awesome\", $language:\"english\"}}" );
StatusWithMatchExpression result = MatchExpressionParser::parse( query );
ASSERT_TRUE( result.isOK() );
MatchExpression* exp = result.getValue();
ASSERT_EQUALS( MatchExpression::TEXT, exp->matchType() );
TextMatchExpression* textExp = static_cast<TextMatchExpression*>( exp );
ASSERT_EQUALS( textExp->getQuery(), "awesome" );
ASSERT_EQUALS( textExp->getLanguage(), "english" );
}
示例4: TEST
TEST( MatchExpressionParserGeoNear, ParseNear ) {
BSONObj query = fromjson("{loc:{$near:{$maxDistance:100, "
"$geometry:{type:\"Point\", coordinates:[0,0]}}}}");
StatusWithMatchExpression result = MatchExpressionParser::parse( query );
ASSERT_TRUE( result.isOK() );
MatchExpression* exp = result.getValue();
ASSERT_EQUALS(MatchExpression::GEO_NEAR, exp->matchType());
GeoNearMatchExpression* gnexp = static_cast<GeoNearMatchExpression*>(exp);
ASSERT_EQUALS(gnexp->getData().maxDistance, 100);
}
示例5: TEST
// For $near, $nearSphere, and $geoNear syntax of:
// {
// $near/$nearSphere/$geoNear: [ <x>, <y> ],
// $minDistance: <distance in radians>,
// $maxDistance: <distance in radians>
// }
TEST(MatchExpressionParserGeoNear, ParseValidNear) {
BSONObj query = fromjson("{loc: {$near: [0,0], $maxDistance: 100, $minDistance: 50}}");
StatusWithMatchExpression result = MatchExpressionParser::parse(query);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
ASSERT_EQ(MatchExpression::GEO_NEAR, exp->matchType());
GeoNearMatchExpression* gnexp = static_cast<GeoNearMatchExpression*>(exp);
ASSERT_EQ(gnexp->getData().maxDistance, 100);
ASSERT_EQ(gnexp->getData().minDistance, 50);
}
示例6: TEST
// For $near, $nearSphere, and $geoNear syntax of:
// {
// $near/$nearSphere/$geoNear: [ <x>, <y> ],
// $minDistance: <distance in radians>,
// $maxDistance: <distance in radians>
// }
TEST(MatchExpressionParserGeoNear, ParseValidNear) {
BSONObj query = fromjson("{loc: {$near: [0,0], $maxDistance: 100, $minDistance: 50}}");
const CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
ASSERT_EQ(MatchExpression::GEO_NEAR, exp->matchType());
GeoNearMatchExpression* gnexp = static_cast<GeoNearMatchExpression*>(exp);
ASSERT_EQ(gnexp->getData().maxDistance, 100);
ASSERT_EQ(gnexp->getData().minDistance, 50);
}
示例7: normalizeTree
// static
MatchExpression* CanonicalQuery::normalizeTree(MatchExpression* root) {
// root->isLogical() is true now. We care about AND and OR. Negations currently scare us.
if (MatchExpression::AND == root->matchType() || MatchExpression::OR == root->matchType()) {
// We could have AND of AND of AND. Make sure we clean up our children before merging
// them.
// UNITTEST 11738048
for (size_t i = 0; i < root->getChildVector()->size(); ++i) {
(*root->getChildVector())[i] = normalizeTree(root->getChild(i));
}
// If any of our children are of the same logical operator that we are, we remove the
// child's children and append them to ourselves after we examine all children.
vector<MatchExpression*> absorbedChildren;
for (size_t i = 0; i < root->numChildren();) {
MatchExpression* child = root->getChild(i);
if (child->matchType() == root->matchType()) {
// AND of an AND or OR of an OR. Absorb child's children into ourself.
for (size_t j = 0; j < child->numChildren(); ++j) {
absorbedChildren.push_back(child->getChild(j));
}
// TODO(opt): this is possibly n^2-ish
root->getChildVector()->erase(root->getChildVector()->begin() + i);
child->getChildVector()->clear();
// Note that this only works because we cleared the child's children
delete child;
// Don't increment 'i' as the current child 'i' used to be child 'i+1'
}
else {
++i;
}
}
root->getChildVector()->insert(root->getChildVector()->end(),
absorbedChildren.begin(),
absorbedChildren.end());
// AND of 1 thing is the thing, OR of 1 thing is the thing.
if (1 == root->numChildren()) {
MatchExpression* ret = root->getChild(0);
root->getChildVector()->clear();
delete root;
return ret;
}
}
return root;
}
示例8: isIndependentOf
bool isIndependentOf(const MatchExpression& expr, const std::set<std::string>& pathSet) {
if (expr.isLogical()) {
// Any logical expression is independent of 'pathSet' if all its children are independent of
// 'pathSet'.
for (size_t i = 0; i < expr.numChildren(); i++) {
if (!isIndependentOf(*expr.getChild(i), pathSet)) {
return false;
}
}
return true;
}
// At this point, we know 'expr' is a leaf. If it is an elemMatch, we do not attempt to
// determine if it is independent or not, and instead just return false.
return !isElemMatch(expr) && isLeafIndependentOf(expr.path(), pathSet);
}
示例9: tagForSort
void tagForSort(MatchExpression* tree) {
if (!Indexability::nodeCanUseIndexOnOwnField(tree)) {
size_t myTagValue = IndexTag::kNoIndex;
for (size_t i = 0; i < tree->numChildren(); ++i) {
MatchExpression* child = tree->getChild(i);
tagForSort(child);
IndexTag* childTag = static_cast<IndexTag*>(child->getTag());
if (NULL != childTag) {
myTagValue = std::min(myTagValue, childTag->index);
}
}
if (myTagValue != IndexTag::kNoIndex) {
tree->setTag(new IndexTag(myTagValue));
}
}
}
示例10: invariant
// static
// XXX TODO: This does not belong here at all.
MatchExpression* CanonicalQuery::logicalRewrite(MatchExpression* tree) {
// Only thing we do is pull an OR up at the root.
if (MatchExpression::AND != tree->matchType()) {
return tree;
}
// We want to bail out ASAP if we have nothing to do here.
size_t numOrs = 0;
for (size_t i = 0; i < tree->numChildren(); ++i) {
if (MatchExpression::OR == tree->getChild(i)->matchType()) {
++numOrs;
}
}
// Only do this for one OR right now.
if (1 != numOrs) {
return tree;
}
// Detach the OR from the root.
invariant(NULL != tree->getChildVector());
std::vector<MatchExpression*>& rootChildren = *tree->getChildVector();
MatchExpression* orChild = NULL;
for (size_t i = 0; i < rootChildren.size(); ++i) {
if (MatchExpression::OR == rootChildren[i]->matchType()) {
orChild = rootChildren[i];
rootChildren.erase(rootChildren.begin() + i);
break;
}
}
// AND the existing root with each or child.
invariant(NULL != orChild);
invariant(NULL != orChild->getChildVector());
std::vector<MatchExpression*>& orChildren = *orChild->getChildVector();
for (size_t i = 0; i < orChildren.size(); ++i) {
AndMatchExpression* ama = new AndMatchExpression();
ama->add(orChildren[i]);
ama->add(tree->shallowClone());
orChildren[i] = ama;
}
delete tree;
// Clean up any consequences from this tomfoolery.
return normalizeTree(orChild);
}
示例11: _extractFullEqualityMatches
static Status _extractFullEqualityMatches(const MatchExpression& root,
const FieldRefSet* fullPathsToExtract,
EqualityMatches* equalities) {
if (root.matchType() == MatchExpression::EQ) {
// Extract equality matches
const EqualityMatchExpression& eqChild =
static_cast<const EqualityMatchExpression&>(root);
FieldRef path(eqChild.path());
if (fullPathsToExtract) {
FieldRefSet conflictPaths;
fullPathsToExtract->findConflicts(&path, &conflictPaths);
// Ignore if this path is unrelated to the full paths
if (conflictPaths.empty())
return Status::OK();
// Make sure we're a prefix of all the conflict paths
Status status = checkPathIsPrefixOf(path, conflictPaths);
if (!status.isOK())
return status;
}
Status status = checkEqualityConflicts(*equalities, path);
if (!status.isOK())
return status;
equalities->insert(make_pair(eqChild.path(), &eqChild));
}
else if (root.matchType() == MatchExpression::AND) {
// Further explore $and matches
for (size_t i = 0; i < root.numChildren(); ++i) {
MatchExpression* child = root.getChild(i);
Status status = _extractFullEqualityMatches(*child, fullPathsToExtract, equalities);
if (!status.isOK())
return status;
}
}
return Status::OK();
}
示例12: stripUnneededAssignments
// static
void QueryPlannerIXSelect::stripUnneededAssignments(MatchExpression* node,
const std::vector<IndexEntry>& indices) {
if (MatchExpression::AND == node->matchType()) {
for (size_t i = 0; i < node->numChildren(); i++) {
MatchExpression* child = node->getChild(i);
if (MatchExpression::EQ != child->matchType()) {
continue;
}
if (!child->getTag()) {
continue;
}
// We found a EQ child of an AND which is tagged.
RelevantTag* rt = static_cast<RelevantTag*>(child->getTag());
// Look through all of the indices for which this predicate can be answered with
// the leading field of the index.
for (std::vector<size_t>::const_iterator i = rt->first.begin();
i != rt->first.end(); ++i) {
size_t index = *i;
if (indices[index].unique && 1 == indices[index].keyPattern.nFields()) {
// Found an EQ predicate which can use a single-field unique index.
// Clear assignments from the entire tree, and add back a single assignment
// for 'child' to the unique index.
clearAssignments(node);
RelevantTag* newRt = static_cast<RelevantTag*>(child->getTag());
newRt->first.push_back(index);
// Tag state has been reset in the entire subtree at 'root'; nothing
// else for us to do.
return;
}
}
}
}
for (size_t i = 0; i < node->numChildren(); i++) {
stripUnneededAssignments(node->getChild(i), indices);
}
}
示例13: TEST
TEST(MatchExpressionParserGeoNear, ParseValidNearSphere) {
BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $maxDistance: 100, $minDistance: 50}}");
const CollatorInterface* collator = nullptr;
const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
StatusWithMatchExpression result =
MatchExpressionParser::parse(query,
collator,
expCtx,
ExtensionsCallbackNoop(),
MatchExpressionParser::kAllowAllSpecialFeatures);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
ASSERT_EQ(MatchExpression::GEO_NEAR, exp->matchType());
GeoNearMatchExpression* gnexp = static_cast<GeoNearMatchExpression*>(exp);
ASSERT_EQ(gnexp->getData().maxDistance, 100);
ASSERT_EQ(gnexp->getData().minDistance, 50);
}
示例14: QLOG
Status SubplanRunner::planSubqueries() {
MatchExpression* theOr = _query->root();
for (size_t i = 0; i < _plannerParams.indices.size(); ++i) {
const IndexEntry& ie = _plannerParams.indices[i];
_indexMap[ie.keyPattern] = i;
QLOG() << "Subplanner: index " << i << " is " << ie.toString() << endl;
}
const WhereCallbackReal whereCallback(_collection->ns().db());
for (size_t i = 0; i < theOr->numChildren(); ++i) {
// Turn the i-th child into its own query.
MatchExpression* orChild = theOr->getChild(i);
CanonicalQuery* orChildCQ;
Status childCQStatus = CanonicalQuery::canonicalize(*_query,
orChild,
&orChildCQ,
whereCallback);
if (!childCQStatus.isOK()) {
mongoutils::str::stream ss;
ss << "Subplanner: Can't canonicalize subchild " << orChild->toString()
<< " " << childCQStatus.reason();
return Status(ErrorCodes::BadValue, ss);
}
// Make sure it gets cleaned up.
auto_ptr<CanonicalQuery> safeOrChildCQ(orChildCQ);
// Plan the i-th child.
vector<QuerySolution*> solutions;
// We don't set NO_TABLE_SCAN because peeking at the cache data will keep us from
// considering any plan that's a collscan.
QLOG() << "Subplanner: planning child " << i << " of " << theOr->numChildren();
Status status = QueryPlanner::plan(*safeOrChildCQ, _plannerParams, &solutions);
if (!status.isOK()) {
mongoutils::str::stream ss;
ss << "Subplanner: Can't plan for subchild " << orChildCQ->toString()
<< " " << status.reason();
return Status(ErrorCodes::BadValue, ss);
}
QLOG() << "Subplanner: got " << solutions.size() << " solutions";
if (0 == solutions.size()) {
// If one child doesn't have an indexed solution, bail out.
mongoutils::str::stream ss;
ss << "Subplanner: No solutions for subchild " << orChildCQ->toString();
return Status(ErrorCodes::BadValue, ss);
}
// Hang onto the canonicalized subqueries and the corresponding query solutions
// so that they can be used in subplan running later on.
_cqs.push(safeOrChildCQ.release());
_solutions.push(solutions);
}
return Status::OK();
}
示例15: _findUser
Status AuthzManagerExternalStateMock::_findUser(const std::string& usersNamespace,
const BSONObj& query,
BSONObj* result) const {
StatusWithMatchExpression parseResult = MatchExpressionParser::parse(query);
if (!parseResult.isOK()) {
return parseResult.getStatus();
}
MatchExpression* matcher = parseResult.getValue();
unordered_map<std::string, std::vector<BSONObj> >::const_iterator mapIt;
for (mapIt = _userDocuments.begin(); mapIt != _userDocuments.end(); ++mapIt) {
for (std::vector<BSONObj>::const_iterator vecIt = mapIt->second.begin();
vecIt != mapIt->second.end(); ++vecIt) {
if (nsToDatabase(usersNamespace) == mapIt->first &&
matcher->matchesBSON(*vecIt)) {
*result = *vecIt;
return Status::OK();
}
}
}
return Status(ErrorCodes::UserNotFound, "User not found");
}