MongoDB: How to query over a json string? - mongodb

There's a MongoDB collection that was populated with documents like this one:
{
"_id" : ObjectId("5b7f83b591fae49715443590"),
"content" : "{\n\t\"email\":\"username#domain.com\",\n\t\"country_code\": \"US\"\n}"
}
As you can see "content"has a JSON string
I was able to parse the string using JSON.parse() like:
db.getCollection('my_collection').find({}).map(function(doc){ return {'_id':doc._id, 'content': JSON.parse(doc.content)}});
Giving me an array of objects with _id and content as an object.
Is there a way to execute queries (filtering, aggregate functions) over content preferably without getting an array from map?

like you said In terms of the database content is a string. So you need to save the entire collection where content will be a object so you will be able to filtering, aggregate etc...

Related

Newbie get _id of returned where query

Selecting specific item from returned query (newbie)
Using laravel with the https://github.com/jenssegers/laravel-mongodb#query-builder package so the php is a bit off the norm for MongoDB terminology
I query the database like so:
$role_id = Role::where('name', 'Admin')->get();
How do I access the '_id' of the returned query?
I would like to grab the '_id' in a variable
get() returns Illuminate\Support\Collection object. That means you are getting an array of return items. So, in your case, you should iterate $role_id to loop through the items and get _id. Like this -
foreach ($rid as $role_id) {
echo $rid->_id;
}

How to remove _id from MongoDB results?

I am inserting json file into Mongodb(with Scala/Play framework) and the same getting/downloading it into my view page for some other requirement, but this time it is coming with one "_id" parameter in the json file.
But I need only my actual json file only that is not having any any "_id" parameter. I have read the Mongodb tutorial, that by default storing it with one _id for any collection document.
Please let me know that how can I get or is there any chance to get my actual json file without any _id in MongoDB.
this is the json result which is storing in database(I don't need that "_id" parameter)
{
"testjson": [{
"key01": "value1",
"key02": "value02",
"key03": "value03"
}],
"_id": 1
}
If you have a look at ReactiveMongo dev guide and to its API, you can see it support projection in a similar way as the MongoDB shell.
Then you can understand that you can do
collection.find(selector = BSONDocument(), projection = BSONDocument("_id" -> 0))
Or, as you are using JSON serialization:
collection.find(selector = Json.obj(), projection = Json.obj("_id" -> 0))
You can use this query in the shell:
db.testtable.find({},{"_id" : false})
Here we are telling mongoDB not to return _id from the collection.
You can also use 0 instead of false, like this:
db.testtable.find({},{"_id" : 0})
for scala you need to convert it in as per the driver syntax.

updating Mongoose documents with nested arrays at multiple indexes

I'm having trouble updating a schema with a nested array to have one objectID in multiple rows of the array. Please help if you can!
My Schema looks like this:
var ProblemSchema = new Schema({
data : "etc..."
array1 : [{
_id : { type: 'String' },
array2: [{ type: Schema.Types.ObjectId}]
}]}
I can easily add an objectId to a SINGLE nested array using the $ operator in the update object like so:
var query = {array1._id : ID};
var update = {$push : {'array1.$.array2' : objectId}};
Problem.update(query, update)
I want to be able to, however, add the same objectId to MULTIPLE array2s (i.e. corresponding to different array1 ids) in one query, but the $ operator only matches to the first match to the query so I can't do it the way outlined above.
I'm also trying to avoid having a for loop on the server (I realize I could find() the correct document then use a for loop in which I manually push() the objectID to the correct array2s but the solution involves large overhead), can anyone think of a solution?
As of MongoDB 2.6, there's no way to do this with with a single update query. The $ positional operator is a placeholder for the first matching element in an array. There's a MongoDB feature request for updating all matching elements of an array, SERVER-1243, that you can track in the meantime.

Updating multiple MongoDB records in Sails.js

I need to update multiple records in mongodb.
From frontend logic , i got the array of id's as below.
ids: [ [ '530ac94c9ff87b5215a0d6e6', '530ac89a7345edc214618b25' ] ]
I have an array of ids as above , i need to update the folder field for all the records in that array.
I tried passing the id's to mongodb query as below , but still that doesn't work.
Post.native(function(err, collection) {
collection.update({
_id : {
"$in" : ids
}
}, { folder : 'X'}, {
multi : true
}, function(err, result) {
console.log(result);
});
});
Please help.
There seem to be two possible problems.
1) your ids array is not an array of ids, it's an array which has a single element which is itself an array, which has two elements. An array of ids would be `[ 'idvalue1', 'idvalue2']
2) your id values inside of arrays are strings - is that how you are storing your "_id" values? If they are ObjectId() type then they are not a string but a type ObjectId("stringhere") which is not the same type and won't be equal to "stringhere".
There is no reason to use the native method in this case. Just do:
Post.update({id : ids}, {folder : 'X'}).exec(console.log);
Waterline automatically does an "in" query when you set a criteria property to an array, and Sails-Mongo automatically translates "id" to "_id" and handles ObjectId translation for you.
Those strings look like the string representation of mongod ObjectIds, so probably what you want to do is turn them into ObjectIds before querying. Assuming you've corrected your problem with the extra level of nesting in the array, that is:
ids = ['530ac94c9ff87b5215a0d6e6', '530ac89a7345edc214618b25']
Then you want to do something like this:
oids = []
for (var i in ids)
oids.push(ObjectId(ids[i]))
db.c.find({_id: {$in: oids}})
Does that fix your problem?

Reference an _id in a Subdocument in another Collection Mongodb

I am developing an application with mongodb and nodejs
I should also mention that I am new to both so please help me through this question
my database has a collection categories and then in each category I am storing products in subdocument
just like below :
{
_id : ObjectId(),
name: String,
type: String,
products : [{
_id : ObjectId(),
name : String,
description : String,
price : String
}]
});
When it comes to store the orders in database the orders collection will be like this:
{
receiver : String,
status : String,
subOrders : [
{
products :[{
productId : String,
name : String,
price : String,
status : String
}],
tax : String,
total : String,
status : String,
orderNote : String
}
]
}
As you can see we are storing _id of products which is a subdocument of categories in orders
when storing there is no issue obviously, when it comes to fetch these data if we just need the limited field like name or price there will be no issue as well, but if later on we need some extra fields from products like description,... they are not stored in orders.
My question is this:
Is there any easy way to access other fields of products apart from loop through the whole categories in mongodb, namely I need a sample code for querying the description of a product by only having its _id in mongodb?
or our design and implementation was wrong and I have to re-design it from scratch and separate the products from categories into another collection?
please don't put links to websites or weblogs that generally talks about mongodb and its collections implementations unless they focus on a very similar issue to mine
thanks in advance
I'd assume that you'd want to return as many product descriptions as matched the current list of products, so first, there isn't a query to return only matching array elements. Using $elemMatch you can return a specific element or the first match, but not only matching array elements. However, $elemMatch can also be used as a projection operator.
db.categories({ "products._id" : "PID1" },
{ $elemMatch : { "products._id" : "PID1" },
"products._id" : 1,
"products.description" : 1})
You'd definitely want to index the "products._id" field to achieve reasonable performance.
You might consider instead creating a products collection where each document contains a category identifier, much like you would in a relational database. This is a common pattern in MongoDb when embedding doesn't make sense, or complicates queries and aggregations.
Assuming that is true:
You'll need to load the data from the second collection manually. There are no joins in MognoDb. You might consider using $in which takes a list of values for a field and loads all matching documents.
Depending on the driver you're using to access MongoDb, you should be able to use the projection feature of find, which can limit the fields returned for a document to just those you've specified.
As product descriptions ardently likely to change frequently, you might also consider caching the values for a period on the client (like a web server for example).
db.products.find({ _id: { $in : [ 'PID1', 'PID2'] } }, { description : 1 })