In MongoDb i have documents with a field named "common_id". I just want to fetch all documents of a particular common_id.
This is how the common_id field looks like.
"common_id" : ObjectId("5911af8209ed4456d069b1d1"),
I have tried this,
$bestAmongAffiliates = MasterAffiliateProductMappingMongo::where('common_id', '=', 'true')
->get();
this,
$bestAmongAffiliates = MasterAffiliateProductMappingMongo::where('common_id', '=', 'ObjectId("5911af8209ed4456d069b1d1")')
->get();
and this,
MasterAffiliateProductMappingMongo::where('common_id', '=', ObjectId("5911af8209ed4456d069b1d1"))
->get();
also tried this,
$bestAmongAffiliates = MasterAffiliateProductMappingMongo::where('common_id', new MongoDB\BSON\ObjectID('5911af8209ed4456d069b1d1'));
I think the problem is that - ObjectId("5911af8209ed4456d069b1d1") is not a string thats why the above codes are not working. Anyway am not sure.
But nothing works. How can i do this.
::where('common_id', '5911af8209ed4456d069b1d1')->get()
should work if you are using Jenssegers Laravel MongoDB.
Checks if it string and string is ctype_xdigit then converts as object in the query builder
Related
I am using Symfony Doctrine Mongodb-odm 1.2 library in the project. group() & reduce() methods are deprecated and no longer available with MongoDB 4.2. My existing code has used these methods to group and pull the MongoDB records using custom reduce logic on the query. Refer the following query:
$customers = $this->createQueryBuilder($business)
->field('pay_status')->equals('unpaid')
->group(['contact' => 0], ['total' => 0])
->reduce(
'function (obj, prev) {
prev.total += obj.total.amount;
prev.contact_data = obj.contact_data;
if (obj.contact) {
prev.contact = obj.contact.$id.str;
}
return prev;
}'
)
->limit(5)
->getQuery()
->execute()
->toArray(false);
This works completely fine with MongoDB 4.0 and returns the result set with top 5 unpaid customers list. Now, I am struggling to find out the replacement for this query using aggregation pipeline which is recommended for MongoDB 4.2.
Can anyone help with the replacement query using aggregation builder methods? I know how to group the result using aggregation stage but not sure how to pull the top 5 customers without reduce() method here. Thanks in advance.
I guess I found the way to query & retrieve the expected result set using aggregation builder without reduce method:
$customers = $this->createAggregationBuilder($business)
->hydrate(false)
->match()
->field('pay_status')->equals('unpaid')
->group()
->field('_id')->expression(['contact_data'=>'$contact_data','contact'=>'$contact'])
->field('total')->sum('$total.amount')
->project()
->field('total')->expression('$total')
->field('contact')->expression('$_id.contact')
->field('contact_data')->expression('$_id.contact_data')
->field('_id')->expression('$$REMOVE')
->sort(['total' => 'desc'])
->limit(5)
->getQuery()
->execute()
->toArray(false);
I have this handler that calls this query builder. I am able to retrieve the records, however they are not sorting correctly.
What i have:
getStuff(req) {
...
return (toSqlName, builder) =>
builder.whereRaw(`${toSqlName('id')} = ANY(?::uuid[]`, [ids]).orderByRaw('username DESC')
}
Seems to work fine except the records coming back are not sorted. I've tried chaining .orderBy('username', 'desc') as well.
You can call .orderBy:
knex.select()
.table('products')
.orderBy('name', 'desc')
.orderBy('id', 'asc')
I'm working on super simple search across multiple fields in a document to see if any of them has a single value. (Note: some fields are using regex to search if value is contained in string). Using query builder I constructed the following.
public function search($value, $limit, $offset=0, $orderby = '', $order='' )
{
$regexVal = new \MongoRegex('/^.*(\b'.str_replace(' ', '\s', $value).'\b).*?$/i');
$query = $this->repository->createQueryBuilder();
$query->addOr($query->expr()->field('location')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.first_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.last_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.email')->equals($value));
$query->addOr($query->expr()->field('email')->equals($value));
$query->addOr($query->expr()->field('organization')->equals($value));
$query->limit($limit)
->skip($offset);
if( ! empty($orderby) && $order ){
$query->sort($orderby, $order);
}
return $query->getQuery()->execute();
}
If I dump out the constructed query values I get the following array in this gist. https://gist.github.com/jchamb/04a0400c989cd28b1841 The extra association field in there is being added by a Doctrine Filter.
Through Query builder I don't get any results, however if I construct the query myself and run it in an admin app like genghis, I get the expected single document result.
Actual written mongodb string looks like this. https://gist.github.com/jchamb/ce60829480576a88290d
This project is a zend2 app that was already using doctrine and mongo. I'm not much of an expert with mongo in general so I'm not sure what i'm doing wrong inside of Query Builder that i'm not getting the same result as executing the query directly. I can't find any info on stack or the query builder docs that gives any extra clues for the multiple addOrs syntax either.
Any help or direction would be really appreciated, in the most basic form I need query builder to get a document where association = x and ( field1 = val or field2 = value).
Thanks!
Really unsure what the exact issue was with the above, but after playing around, switching the order of query builder around fixes the problem.
public function search($value, $limit, $offset=0, $orderby = '', $order='' )
{
$regexVal = new \MongoRegex('/^.*(\b'.str_replace(' ', '\s', $value).'\b).*?$/i');
$query = $this->repository->createQueryBuilder()
->find()
->limit($limit)
->skip($offset);
$query->addOr($query->expr()->field('location')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.first_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.last_name')->equals($regexVal));
$query->addOr($query->expr()->field('mappedData.email')->equals($value));
$query->addOr($query->expr()->field('email')->equals($value));
$query->addOr($query->expr()->field('organization')->equals($value));
if( ! empty($orderby) && $order ){
$query->sort($orderby, $order);
}
return $query->getQuery()->execute();
}
Would love to still hear some feedback about why this works and the above didn't if anyone know more about the internals of query builder.
I am doing a query on a result document in my doctrine mongodb *odm*. There are two indexed fields in the document which I would like to use in sort. I have written something like:
$results = $this->createQueryBuilder('Document\Score')
->sort('finalScore', 'desc')
->sort('date', 'desc')
->getQuery()
->execute();
Here the second sort() function overrides the first one and the designated result is never found.
Thanks in advance for the nice help.
Try this
$qb = $this->createQueryBuilder('Document\Score');
$qb->sort(array(
'finalScore' => 'desc',
'date' => 'desc',
));
$results = $qb->getQuery()->execute();
I can't figure out how to change the value of a field in a nested document in a MongoDB document via the Mongoose Node.js JavaScript ORM. Code in CoffeeScript:
mongoose = require 'mongoose'
mongoose.connect 'mongodb://localhost/test'
Schema = mongoose.Schema
Page = new Schema
content: String
Article = new Schema
_id: String
pages: [Page]
article_model = mongoose.model 'Article', Article, 'testcollection'
article_model.findOne({_id: 'id1'}, (err, article) =>
article.pages[0].content = 'foo'
article.save()
)
The next time I fetch article, article.pages[0].content still has its original value, although there is no error on the save().
I suspect I need to reference content differently... but how? Thanks!
Edit: It works if I do something like this:
for page in article.pages
if page is whatever
page.content = 'foo'
article.save()
However, that seems pretty inelegant and inefficient.
You have to use the update function.