Mongodb: searching embedded documents by the '_id' field - mongodb

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"})

Related

MongoDB search via index of documents containing JSON

Say I have objects in a MongoDB collection:
{
...
"json" : "{\"things\":[2494090781803658355,5114030115038563045,3035856943768375362,8931213615561493991,7574631742057150605,480863244020297489]}"
}
It's an Azure "MongoDB" so doesn't support all the features, but suppose it does.
This search will find that document:
db.coll.find({"json" : {$regex : "5114030115038563045|8931213615561493991"}})
Of course, it's scanning the whole collection to pull these records out. What's an efficient/faster way to find documents where the list of "things"
contains any of a list of "things" in a query? It seems like throwing a search engine like Solr or ElasticSearch would solve this, and perhaps
using another Azure's Data Lake storage would make this more searchable, so I'm considering those options. They're outside the scope of this
question though; I'd like to know if there's a Mongo-ish way to search this collection by index.
The only option you have available to you if you're storing a JSON string is to use a text index with a $text operator.
If this document structure isn't set in stone, however, you might consider also separately storing the JSON as a nested subdocument (with the appropriate sanitation, of course). This would allow you to construct an index on json.things, while still storing the JSON string, and allow you to perform a query on e.g. "json.things": {$in: [ "5114030115038563045", "8931213615561493991" ]}

MongoDB index for nested document is not being used

In my collection, I've say the following structure
{
_id: ObjectId("ssxxdfasfsadf"),
a: {
b: "somevalue"
}
}
I've created an index for a.b, which works fine if I use find query as db.collection.find({"a.b": "someothervalue"}).
If I change my query to db.collection.find({a: {b: "somevalue"}}), it's doing a complete collection scan. (Source - find().explain())
Sure, I can modify my application to do the query as "a.b", but I want to avoid that, as I've few other fields in a, on which in future I may need to query.
Is there anyway {a: {b: "somevalue"}} could work with tweaking the index?
Also, is there any advantage/disadvantage of using one or the other?
I would go with the first approach. A quick read through MongoDB's documentation, states the following:
MongoDB uses the dot notation to access the elements of an array and to access the fields of an embedded document.
See MongoDB Dot Notation and Query on Embedded/Nested Documents.
About tweaking the index, you could index the embedded document as a whole:
db.myColl.createIndex({ "a": 1 });
But I don't see the reason of doing this if you only need specific properties indexed. I would be sensitive on the Index Size, especially if the property will be holding a lot of data.

Is there a way to implement "find or aggregate" using single operation in MongoDB?

I have a collection of simple documents like:
{tag: "...", data: {...}}
What i want to do is to find a document with given tag and make a projection from its data. But if this document cannot be found, i want to aggregate data from another documents.
I wonder if there is a way to make it using single operation.

mongodb query on DBRef type

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

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.