i seem to only be having this issue with 1 particular model when i am searching by ID
>> Cart.where(:_id => '4dae5902e1607c232c000009').first
=> #<Cart _id: 4dae5902e1607c232c000009, _id: BSON::ObjectId('4dae5902e1607c232c000009'), _type: nil>
>> Cart.find('4dae5902e1607c232c000009')
Mongoid::Errors::DocumentNotFound: Document not found for class Cart with id(s) 4dae5902e1607c232c000009.
the strange thing is that with other models, i can use find just fine. any ideas?
the rest of the stack is...
from /Library/Ruby/Gems/1.8/gems/mongoid-2.0.1/lib/mongoid/criterion/inclusion.rb:192:in `execute_or_raise'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.0.1/lib/mongoid/criterion/inclusion.rb:190:in `tap'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.0.1/lib/mongoid/criterion/inclusion.rb:190:in `execute_or_raise'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.0.1/lib/mongoid/criterion/inclusion.rb:106:in `find'
from /Library/Ruby/Gems/1.8/gems/mongoid-2.0.1/lib/mongoid/finders.rb:67:in `find'
from (irb):37
Normally the issue is the other way around. With the where failing and the find working.
That is cause by where not casting the id into BSON::ObjectId before the query.
Usually you would have to do this
Cart.where(:_id => BSON::ObjectId('4dae5902e1607c232c000009')).first
This leads me to believe that your ids are stored as strings and not BSON:ObjectId and would explain why find fails ( it is searching for a BSON::ObjectId not a string)
Could also explain why it is only one model as it depends entirely on how the objects are stored.
Hope that helps
Related
I have the following problem, I have already done some research in the net and here, but no solution found so far, I would be glad to receive suggestions.
Consider the code:
myModel.create(array).then((justCreated)=>
{
//justCreated is the array of document just created, I can print them out and see!
})
My problem is: I just need their ids, on a array if possible. I could take one by one, but, is there a better way?
I have tried setting the second parameter to "_id" like we do with find or select like we do with populate, but no success. Any suggestion?
PS. I am using mongoose.
According to this post you can see that forEach is much slower than map method. So i think a better solution is the following
myModel.create(array)
.then(justCreated => {
const idsArray = justCreated.map(el => el._id);
})
.catch(err => console.log(err));
After giving some extra thoughts, I have come up with the solution, which I am afraid regarding performace, since my dataset is pretty big, that is the reason I cannot use subdocument, I have tried, but I exceed easily the 16MB maximum limit.
myModel.create(array).then((justCreated)=>
{
justCreated.ForEach((doc)=>{id.push(doc.id))
})
I am opened to suggestion for better ways to handle this problem but this seems to solve the problem, at least at first glance.
I'm returning collection results via a basic find() query and something odd is happening to the {{_id}} I'm receiving. Instead of just the unique id, I'm getting a bunch of trailing garbage that looks like other parts of the document. This is only happening for one collection - the exact same query works perfectly with all my other collections. I'm thinking it may have something to do with how I'm adding collection items, but I'm pretty lost. I can provide more info if needed, but I thought perhaps someone had encountered this before and could advise based on what I've described.
Here's what {{_id}} looks like for documents in the problematic collection:
3D5DWGh9n96BuiC4P""%7B"userId":"hJhLm8iBL9cQDEhzf","limit":10,"skip":0,"props":%7B%7D%7D
Anyone know what's going on here?
NB: Here's extra information I stupidly omitted the first time:
The trailing stuff is not returned when I do I find().fetch(). It's only when I use the easy-search package ( link ) that this happens. Sorry for the lack of clarity earlier.
The helper:
Template.search.helpers({
articlesIndex: () => ArticlesIndex
});
...relevant parts of the template:
{{> EasySearch.Input index=articlesIndex}}
<ul>
{{#EasySearch.Each index=articlesIndex}}
<li>{{title}}</li>
{{/EasySearch.Each}}
</ul>
The hrefs in the search results are where the problematic _ids are.
Actually, it looks like I've figured it out. According to the issues on github, _id is used by the package so I have to refer to __originalId instead. Here's a link in case it helps anyone else: link
here's my model:
class Person
acts_as_tree
end
i relate multiple objects as a tree:
P1
|
---
| |
P1.1 P1.2
|
---
| |
P1.1.1 P1.1.2
here if i need to retreive P1.1.1 i need to write a query that effectively asks:
get me the Person with name P1.1.1 and path (given by acts_as_tree) [P1, P1.1].
querying by just name is not enough as i can have similar named people at multiple paths.
how do i do this?
> db.people.find({name: 'P1.1.1'})
above snippet will show me the path attribute correctly as expected, but i cannot query by that path.
> db.people.find({name: 'P1.1.1', path: [{name: 'P1'}, {name: 'P1.1'}]})
doesn't work. neither does:
> db.people.find({name: 'P1.1.1', path: [db.people.find({name: 'P1'}),
db.people.find({name: 'P1.1'})]})
but that explains what i'm trying to do.
One of the ways where you can query something like as follows:
db.people.find({name : 'Joe', 'path' : { $all : [ObjectId("4e0fcf1722b7a9439200002e"), ObjectId("4e0fcf1622b7a9439200002b")]}})
However the drawback I think of this is:
You don't get to substitute the object relations/joins directly in mongo shell. You have to use the ObjectId object
The $all clause does not necessitate that the order of path is strictly same, which means that a person with name "Joe" referenced by path "hometown/town/" would come up as well as "Joe" from "tome/hometown".
I would presume that second one may be a deal breaker. Also, I am presuming that mongoid in several cases pass across the query options directly to mongodb (or atleast there are ways to do that). Hence it should be possible to do a search in ruby code using given query above.
Nevertheless, I'll do some more re-search on this and post my findings back.
Hope it helps.
Edit
To alleviate the second problem above there is also another way to query a person with a specific path. Find it below:
db.people.find({name : 'Joe', 'path.0' :ObjectId("4e0fcf1722b7a9439200002e"), 'path.1':ObjectId("4e0fcf1622b7a9439200002b")})
This would ensure that path is exactly what you are looking for. However this works in mongodb shell and you may still need to figure out, how mongoid can run an equivalent of this. Plus you may have to construct this query dynamically to create a path for person and that (for deep nested people) may just become long and ugly.
I would suggest skimming through following links on mongodb documentation to get a better understanding.
http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray
I hope this is what you were looking for.
This is the sample code :
$r = $coll->findOne();
$coll->remove(array("_id"=>$r["_id"])); // use the same object id as retreived from DB
$ret=$coll->findOne(array("_id"=>($r["_id"])));
var_dump($ret); // dumps the records that was supposed to be deleted
The records in the collection have MongoDB objectId, and not strings.
Same logic on console works fine and deleted the record correctly.
This is working for me. Here's the code:
$coll->drop();
print("Now have ".$coll->count()." items\n");
$coll->insert(array("x" => 'blah'));
$coll->insert(array("x" => "blahblah"));
print("Inserted ".$coll->count()." items\n");
$x = $coll->findOne();
print("Object X\n");
print_r($x);
$query_x = array('_id' => $x['_id']);
$coll->remove($query_x);
print("Removed 1 item, now have ".$coll->count()." items\n");
$y = $coll->findOne($query_x);
print("Object Y\n");
print_r($y);
Here's the output:
Now have 0 items
Inserted 2 items
Object X
Array
(
[_id] => MongoId Object
(
[$id] => 4d8d124b6803fa623b000000
)
[x] => blah
)
Removed 1 item, now have 1 items
Object Y
Are you sure there's not a typo somewhere?
Unlike the php == operator, mongo's equality operator always uses "Object equality" which is like php's identical comparison operator (===) or java's .equals(). While your code looks as though it should work (and it does work fine for me with a test dataset), something about your dataset may be causing php to cast the returned MongoId to a string. Read more about MongoId here.
Make sure that your query is supplying a MongoId for comparison by doing a var_dump of the query itself. Also, make sure that you are running the latest version of the PHP Mongo driver.
Since PHP is loosely typed it is most important to ensure that you cast all input values and search values to the expected and consistent data type otherwise it will surely not locate your expected document.
While using MongoDB within PHP I make it a point to cast everything intentionally in order to avoid any possible confusion or error.
Also, the mongodb-user group at groups.google.com is very good and responsive so if you are not already utilizing that resource I would definitely consider joining it.
I have an app using Mongoid on top of MongoDB and an update is failing silently.
The code looks like this:
# Are we getting a new attribute? Yes we are!
p "attr first name = #{#attributes['first_name']}"
if user.update_attributes!(#attributes)
u = User.find(params[:id]).to_json
end
No exception is thrown in this code. So I looked at my MongoDB log and constructed this query based on what mongo is trying to do:
db.users.update({ "_id": "4d5561276ce886c496000001" }, { $set: { "first_name": "Erinamodobo" } }, false);
Now this does not cause any exceptions but when I grab the record that was supposed to be updated with this query:
db.users.find({"email":"escharling#somecompany.com"})
I see that the "first_name" attribute has not been updated.
Any idea why this could be happening? Sounds like something stupid.
Thanks!
You need to find out what
user.update_attributes!(#attributes)
is actually doing. This could be an issue with Mongoid. When you configure Mongoid, you can set up a logger. There you should be able to see what the driver is writing to MongoDB, and that should help answer your question. The next best thing is to post your code to the Mongoid mailing list (http://groups.google.com/group/mongoid) where people who work with Mongoid all the time will probably know what's going on.
Updating Mongoid to the latest rc.7 fixed this issue
Enable "safe mode" on your operations.