mongodb query on DBRef type - mongodb

How do I turn this query in a valid mongodb Query in mongodb shell.
{ 'cars.owner.$ref' : 'users' }
cars.owner is a DBRef here, but $ref is invalid
I get this error:
"$err" : "Positional operator does not match the query specifier."
My objective here is to figure out if there are any cars "owned" by different collections then users.

You can query the DBRef in the Mongo shell, but you have to use the DBRef() function. The reference must include at least the $ref and $id. From the docs:
DBRef documents resemble the following document:
{ "$ref" : <value>, "$id" : <value>, "$db" : <value> }
When cars.owner is a reference to a document in the users collection, a query to find all cars where owner is a certain _id might look like (assuming both collections are in the same database):
db.cars.find({ "owner" : DBRef("users", ObjectId("<user _id value>")) })
The $ref and $id values cannot be queried directly. The DBRef is most useful in the case where there are multiple references to different collections in the same document. Using DBRef might be overkill when there is only one reference in the document, as others have mentioned.
If you need to reference different collections in your owners field, you are probably better served by using separate owner_collection and owner_id fields. The query to find all owners that are not users would then be a standard query:
db.cars.find({ owner_collection: { $ne: "users" } })

MongoDB documentation (database-reference) says following:
MongoDB applications use one of two methods for relating documents:
Manual references where you save the _id field of one document in another document as a reference. Then your application can run a second query to return the related data. These references are simple and sufficient for most use cases.
DBRefs are references from one document to another using the value of the first document’s _id field, collection name, and, optionally, its database name. By including these names, DBRefs allow documents located in multiple collections to be more easily linked with documents from a single collection. To resolve DBRefs, your application must perform additional queries to return the referenced documents. Many drivers have helper methods that form the query for the DBRef automatically. The drivers 1 do not automatically resolve DBRefs into documents.
I don't know about any plans, but I have read that DBRefs should be deprecated(?) nowadays. However, you can use fetch() -method to load referenced documents. For example, I have formView collection which stores documents that contains (DBRef) references to documents in formContent collection. So, running:
var view = db.formView.findOne()
view.formContent
view.formContent.fetch()
view.formContent.fetch().code
...Will result in following output:
DBRef("formContent", ObjectId("56cb155ea826872b67373e76"))
{
"_id" : ObjectId("56cb155ea826872b67373e76"),
"code" : "test_content",
"version" : 0
}
test_content

<parameterName>: DBRef("CollectionName", "_id Value")
put in collection.Then Create a Bean having feild name as parameterName, and put #Reference annotation of morphia orm then do operations you want

Related

Mongodb: searching embedded documents by the '_id' field

If I have a data with a structure like this as a single document in a collection:
{
_id: ObjectId("firstid"),
"name": "sublimetest",
"child": {
_id: ObjectId("childid"),
"name": "materialtheme"
}
}
is there a way to search for the embedded document by the id "childid" ?
because mongo doesn't index the _id fields of embedded documents (correct me if I am wrong here),
as this query doesn't work :
db.collection.find({_id:"childid"});
Also please suggest me if there is any other document database that would be suitable for this kind of retreiving data that is structured as a tree, where the requirement is to :
query children without having to issue joins
find any node in the tree as fast as you would find the root node, as if all these nodes were stored as separate documents in a collection.
Why this is not a duplicate of question(s) suggested :
the potential-duplicate-question, queries document by using dot notation. But what if the document is nested 7 levels deep ? In such case it would not be suitable to write a query using dot notation. what I want is that, all documents, whether top level, or nested, if they have the _id field, should be in the bucket of _id indexes, so that when you search db.collection.find({_id: "asdf"}), it should take into account documents that are nested too that have the _id field matching "asdf". In short, it should be as if the inner document weren't nested, but present parallel to the outer one.
You can use the dot notation:
db.posts.find({"child._id": "childid"})

How to remove document from all collections in Mongo database

I have Mongo database with 16 collections. All collection has the common field domain_id.
How can I remove documents with specified domain_id from all collections.
I know only how to remove document from single collection.
db.getCollection('collectionName1').remove({domain_id : '123'})
Use the method db.getCollectionNames() to get a list of all the collections in your database, iterate the list using the JavaScript's forEach()
method to remove the document from each collection:
db.getCollectionNames().forEach(function (col) {
db.getCollection(col).remove({domain_id : '123'})
});
Unfortunately, Mondo doesn't allow for linking collections. So, you do have to do it for each separate collection.

Denormalization Data in MongoDb Doctrine Symfony 2

I'm Following this Doc
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/tutorials/getting-started.html
And
http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html
When I Save My Document, I have two Collection
like this:
{
"_id" : ObjectId("5458e370d16fb63f250041a7"),
"name" : "A Foo Bar",
"price" : 19.99,
"posts" : [
{
"$ref" : "Embedd",
"$id" : ObjectId("5458e370d16fb63f250041a8"),
"$db" : "test_database"
}
]
}
I'd like have
{
"_id" : ObjectId("5458e370d16fb63f250041a7"),
"name" : "A Foo Bar",
"price" : 19.99,
"posts" : [
{
"mycomment" :"dsdsds"
" date" : date
}
]
}
I want denormalization my data. How Can i Do it?
Can I use Methods like $push,$addToSet etc of mongoDb?
Thanks
Doctrine ODM supports both references and embedded documents.
In your first example, you're using references. The main document (let's assume it's called Product) references many Post documents. Those Post documents live in their own collection (for some reason this is named Embedd -- I would suggest renaming that if you keep this schema). By default, ODM uses the DBRef convention for references, so each reference is itself a small embedded document with $ref, $id, and $db fields.
Denormalization can be achieved by using embedded documents (an #EmbedMany mapping in your case). If you were embedding a Post document, the Post class should be mapped as an #EmbeddedDocument. This tells ODM that it's not a first-class document (belonging to its own collection), so it won't have to worry about tracking it by _id and the like (in fact, embedded documents won't even need identifiers unless you want to map one).
My rule of thumb for deciding to embed or references has generally been asking myself, "Will I need this document outside of the context of the parent document?" If a Post will not have an identity outside of the Product record, I'm comfortable embedding it; however, if I find later that my application also wants to show users a list of all of their Posts, or that I need to query by Posts (e.g. a feed of all recent Posts, irrespective of Product), then I may want to reference documents in a Posts collection (or simply duplicate embedded Posts as needed).
Alternatively, you may decide that Posts should exist in both their own collection and be embedded on Product. In that case, you can create an AbstractPost class as a #MappedSuperclass and define common fields there. Then, extend this with both Post and EmbeddedPost sub-classes (mapped accordingly). You'll be responsible for creating some code to generate an EmbeddedPost from a Post document, which will be suitable for embedding in the Product.posts array. Furthermore, you'll need to handle data synchronization between the top-level and embedded Posts (e.g. if someone edits a Post comment, you may want all the corresponding embedded versions updated as well).
On the subject of references: ODM also supports a simple option for reference mappings, in which case it will just store the referenced document's _id instead of the larger DBRef object. In most cases, having DBRef store the collection and database name for each referenced document is quite redundant; however, DBRef is actually useful if you're using single-collection inheritance, as ODM uses the object to store extra discriminator information (i.e. the class of the referenced object).

Mongo _id for subdocument array

I wish to add an _id as property for objects in a mongo array.
Is this good practice ?
Are there any problems with indexing ?
I wish to add an _id as property for objects in a mongo array.
I assume:
{
g: [
{ _id: ObjectId(), property: '' },
// next
]
}
Type of structure for this question.
Is this good practice ?
Not normally. _ids are unique identifiers for entities. As such if you are looking to add _id within a sub-document object then you might not have normalised your data very well and it could be a sign of a fundamental flaw within your schema design.
Sub-documents are designed to contain repeating data for that document, i.e. the addresses or a user or something.
That being said _id is not always a bad thing to add. Take the example I just stated with addresses. Imagine you were to have a shopping cart system and (for some reason) you didn't replicate the address to the order document then you would use an _id or some other identifier to get that sub-document out.
Also you have to take into consideration linking documents. If that _id describes another document and the properties are custom attributes for that document in relation to that linked document then that's okay too.
Are there any problems with indexing ?
An ObjectId is still quite sizeable so that is something to take into consideration over a smaller, less unique id or not using an _id at all for sub-documents.
For indexes it doesn't really work any different to the standard _id field on the document itself and a unique index across the field should work across the collection (scenario dependant, test your queries).
NB: MongoDB will not add an _id to sub-documents for you.

MongoDB - DBRef to a DBObject

Using Java ... not that it matters.
Having a problem and maybe it is just a design issue.
I assign "_id" field to all of my documents, even embedded ones.
I have a parent document ( and the collection for those ) which has an embedded document
So I have something like:
{ "_id" : "49902cde5162504500b45c2c" ,
"name" : "MongoDB" ,
"type" : "database" ,
"count" : 1 ,
"info" : { "_id" : "49902cde5162504500b45c2y",
"x" : 203 ,
"y" : 102
}
}
Now I want to have another document which references my "info" via a DBRef, don't want a copy. So, I create a DBRef which points to the collection of the parent document and specifies the _id as xxxx5c2y. However, calling fetch() on the DBRef gives a NULL.
Does it mean that DBRef and fetch() only works on top level collection entry "_id" fields?
I would have expected that fetch() would consume all keys:values within the braces of the document .. but maybe that is asking too much. Does anyone know?? Is there no way to create cross document references except at the top level?
Thanks
Yes, your DBRef _id references need to be to documents in your collection, not to embedded documents.
If you want to find the embedded document you'll need to do a query on info._id and you'll need to add an index on that too (for performance) OR you'll need to store that embedded document in a collection and treat the embedded one as a copy. Copying is OK in MongoDB ... 'one fact one place' doesn't apply here ... provided you have some way to update the copy when the main one changes (eventual consistency).
BTW, on DBRef's, the official guidance says "Most developers only use DBRefs if the collection can change from one document to the next. If your referenced collection will always be the same, the manual references outlined above are more efficient."
Also, why do you want to reference info within a document? If it was an array I could understand why you might want to refer to individual entries but since it doesn't appear to be an array in your example, why not just refer to the containing document by its _id?