copyValue from another collection in MongoDb - javascript

Can i Copy Some Field from collection to another collection?
I want copy values of bar to foo collection, but i don't want type filed, and I want insert in foo e new _id e extra field (userId) ( then i use Node.js)
collection bar
{
"_id" : ObjectId("77777777ffffff9999999999"),
"type" : 0,
"name" : "Default",
"index" : 1,
"layout" : "1",
}
collection foo
{
"_id" : NEW OBJECT ID,
// "type" : 0, NO IN THIS COLLECTION
"userId" : ObjectId("77777777ffffff9999999911"),
"name" : "Default",
"index" : 1,
"layout" : "1",
}
I try with db.bar.copyTo("foo"); but copy entire collection

Actually that is probably your best option. But when you don't want the new field in your collection, then just remove it using $unset:
db.foo.update({ },{ "$unset": { "type": 1 } },false,true)
That will remove the field from all documents in your new collection in one statement.
In future releases from 2.6 and upwards you can also do this using aggregate:
db.bar.aggregate([
{ "$project": {
"userId" : 1
"name" : 1
"index" : 1
"layout" : 1
}},
{ "$out": "foo" }
])
The new $out method sends the output of the aggregation statement to a collection.

You can copy fields from one collection to another by using
db.copyFromCollection.find().forEach(function(x){
db.copyToCOllection.update(
{"_id" : ObjectId("53205a4a14952bee39f3376e")}, //some condition for update
{ $set:{parameterOfCopyToCollection:x.parameterOfCopyFromCollection}
});
});
Here we iterate through the data by using the above function.We iterate through the collection from which we want to copy the data and then inside the function we update the document to which we want to add/update that data.

Related

Sending the result of a mongoDB view to another collection ( INSERT....SELECT from SQL )

I could create a big query, and turn it into a view. Let's call it DBA_VIEW.
db.DBA_VIEW.find()
I'm using noSQLbooster to interact with mongodb and I'm trying to insert the result of this view into another collection.
I don't want to "right click > export" because I need to do this via noSQLbooster itself.
I've seen some querie sthat can do the trick, but, as a SQL SERVER dba, I think I can't get the logic behind, let's say, this one below:
db.full_set.find({date:"20120105"}).forEach(function(doc){
db.subset.insert(doc);
});
how can I use such approach to do my taks?
I just need the result of that view from a collection, to be inserted in another collection, then after this we are going to export the data into a .json file or even a .TXT.
You can design the query in the following way so that the output is directly inserted in a new collection('subset' in this example) without iterating through the result set.
db.full_set.aggregate([
{
$match:{
"date":"20120105"
}
},
{
$out:"subset"
}
])
If 'full_set' has the following documents:
{
"_id" : ObjectId("5d423675bd542251420b6b8e"),
"date" : "20130105",
"name" : "Mechanic1"
}
{
"_id" : ObjectId("5d423675bd542251420b6b8f"),
"date" : "20120105",
"name" : "Mechanic2"
}
{
"_id" : ObjectId("5d423675bd542251420b6b90"),
"date" : "20120105",
"name" : "Mechanic3"
}
With the above query, the 'subset' collection would be having the following documents:
{
"_id" : ObjectId("5d423675bd542251420b6b8f"),
"date" : "20120105",
"name" : "Mechanic2"
}
{
"_id" : ObjectId("5d423675bd542251420b6b90"),
"date" : "20120105",
"name" : "Mechanic3"
}

Meteor: Return only single object in nested array within collection

I'm attempting to filter returned data sets with Meteor's find().fetch() to contain just a single object, it doesn't appear very useful if I query for a single subdocument but instead I receive several, some not even containing any of the matched terms.
I have a simple mixed data collection that looks like this:
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e7"),
"name" : "Entertainment",
"items" : [
{
"_id" : ObjectId("57a38b5f2bd9ac8225caff06"),
"slug" : "this-is-a-long-slug",
"title" : "This is a title"
},
{
"_id" : ObjectId("57a38b835ac9e2efc0fa09c6"),
"slug" : "mc",
"title" : "Technology"
}
]
}
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e8"),
"name" : "Sitewide",
"items" : [
{
"_id" : ObjectId("57a38bc75ac9e2efc0fa09c9"),
"slug" : "example",
"name" : "Single Example"
}
]
}
I can easily query for a specific object in the nested items array with the MongoDB shell as this:
db.categories.find( { "items.slug": "mc" }, { "items.$": 1 } );
This returns good data, it contains just the single object I want to work with:
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e7"),
"items" : [
{
"_id" : ObjectId("57a38b985ac9e2efc0fa09c8")
"slug" : "mc",
"name" : "Single Example"
}
]
}
However, if a similar query within Meteor is directly attempted:
/* server/publications.js */
Meteor.publish('categories.all', function () {
return Categories.find({}, { sort: { position: 1 } });
});
/* imports/ui/page.js */
Template.page.onCreated(function () {
this.subscribe('categories.all');
});
Template.page.helpers({
items: function () {
var item = Categories.find(
{ "items.slug": "mc" },
{ "items.$": 1 } )
.fetch();
console.log('item: %o', item);
}
});
The outcome isn't ideal as it returns the entire matched block, as well as every object in the nested items array:
{
"_id" : ObjectId("570d20de3ae6b49a54ee01e7"),
"name" : "Entertainment",
"boards" : [
{
"_id" : ObjectId("57a38b5f2bd9ac8225caff06")
"slug" : "this-is-a-long-slug",
"name" : "This is a title"
},
{
"_id" : ObjectId("57a38b835ac9e2efc0fa09c6")
"slug" : "mc",
"name" : "Technology"
}
]
}
I can then of course filter the returned cursor even further with a for loop to get just the needed object, but this seems unscalable and terribly inefficient while dealing with larger data sets.
I can't grasp why Meteor's find returns a completely different set of data than MongoDB's shell find, the only reasonable explanation is both function signatures are different.
Should I break up my nested collections into smaller collections and take a more relational database approach (i.e. store references to ObjectIDs) and query data from collection-to-collection, or is there a more powerful means available to efficiently filter large data sets into single objects that contain just the matched objects as demonstrated above?
The client side implementation of Mongo used by Meteor is called minimongo. It currently only implements a subset of available Mongo functionality. Minimongo does not currently support $ based projections. From the Field Specifiers section of the Meteor API:
Field operators such as $ and $elemMatch are not available on the client side yet.
This is one of the reasons why you're getting different results between the client and the Mongo shell. The closest you can get with your original query is the result you'll get by changing "items.$" to "items":
Categories.find(
{ "items.slug": "mc" },
{ "items": 1 }
).fetch();
This query still isn't quite right though. Minimongo expects your second find parameter to be one of the allowed option parameters outlined in the docs. To filter fields for example, you have to do something like:
Categories.find(
{ "items.slug": "mc" },
{
fields: {
"items": 1
}
}
).fetch();
On the client side (with Minimongo) you'll then need to filter the result further yourself.
There is another way of doing this though. If you run your Mongo query on the server, you won't be using Minimongo, which means projections are supported. As a quick example, try the following:
/server/main.js
const filteredCategories = Categories.find(
{ "items.slug": "mc" },
{
fields: {
"items.$": 1
}
}
).fetch();
console.log(filteredCategories);
The projection will work, and the logged results will match the results you see when using the Mongo console directly. Instead of running your Categories.find on the client side, you could instead create a Meteor Method that calls your Categories.find on the server, and returns the results back to the client.

MongoDB and Mongoose: How to retrieve nested Object

I have the following documents in my mongodb collection:
{
"current" :
{
"aksd" : "5555",
"BullevardBoh" : "123"
},
"history" :
{ "1" : {
"deleted" : false,
"added" : false,
"date" : "21-08-2014"
}
},
{ "2" : {
"deleted" : false,
"added" : false,
"date" : "01-01-2013"
}
},
"_id" : ObjectId("53f74dad2cbfdc136a07bf16"),
"__v" : 0
}
I have multiple of these documents. Now I want to achieve two things with my Mongoose/Express API.
Query for all nested "current" in each document and retrieve them as JSON objects like such: {"aksd":"5555","BullevardBoh":"123"},{..},{..}.
Retrieve all history revisions (1,2...) where "date" is smaller than a given date.
As you can clearly see this is a kind of versioning I am trying to implement. I would also be interested if this kind of data structure will get indexed by MongoDB and if there is possibly a better way. (e.g. with arrays inside objects?)
This isn't working in MongoDB:
db.ips.findOne({current.aksd: {$exists:true}});
I think the quotes around the field are missing here:
db.ips.findOne({current.aksd: {$exists:true}});
This should work instead:
db.ips.findOne({"current.aksd": {$exists:true}});
While Ritesh's reply was a step in the right direction, I rather wanted to fetch the current object literal and its members inside the document not the whole document.
1.) Query for all nested "current" in each document
db.ips.find({"current":{$exists:true}}, {"current":1});
This is giving back all nested documents where the aksd literal is present:
{ "current" : { "aksd" : "5555", "BullevardBoh" : "123" }, "_id" : ObjectId("53f74dad2cb3dc136a07bf16") }
...
2.) Retrieving history revisions where date is smaller then a given date:
db.ips.find({"history.date": {$lt: "01-01-2014"}},{history:{$elemMatch:{date: {$lt:"01-01-2014"}}}});
Giving back the wanted nested date literal(s):
{ "historie" : [ { "date" : "01-01-2013", "added" : false, "deleted" : false } ], "_id" : ObjectId("53faf20f399a954b2b7736b6") }

Fetch issues in backbone collection with id

Following is my JSON:
[
{
"id" : "1",
"type" : "report"
},
{
"id" : "2",
"type" : "report"
},
{
"id" : "1",
"type" : "email"
},
]
Consider, json is returned from backbone collection -> service call.
Now, when I'm using the json response to render my html table using backbone view and handlebars template system.
2 rows gets displayed, instead there should be 3 rows.
Note:
collection Parse response is returning correct json (i.e. 3 rows).
When I overwrite the id using collection parse with unique random generated number all 3 rows get displayed.
This is not ok, because I don't want to change the id.
I want the row to be displayed as following:
1 reports
2 reports
1 email
From the documentation for Collection add,
Note that adding the same model (a model with the same id) to a
collection more than once is a no-op.
While I cannot see a reason for why two different objects should have the same id, you may have a valid reason. One suggestion would be to add another property to each object in the json response, _dummyId and set that to an autoincrementing value from the server side. On the client side, in your model definition code, you then set the idAttribute to _dummyId.
JSON response,
[
{
"id" : "1",
"_dummyId": "1",
"type" : "report"
},
{
"id" : "2",
"_dummyId": "2",
"type" : "report"
},
{
"id" : "1",
"_dummyId": "3",
"type" : "email"
},
]
Your model definition, from http://backbonejs.org/#Model-idAttribute,
var Meal = Backbone.Model.extend({
idAttribute: "_dummyId"
});
That said, I do hope there is an elegant setting in backbone, something that makes a backbone collection acts a list instead of a set.
If you want to solve this, you have to set new unique id for each model you add to collection.
Try this method:
initialize: function() {
this.set("id", this.generateID());
},
generateID = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
If you need the original id, you need to save it before, and after create the new one, you set the original in another model attribute.
Backbone ignore me when I did #amith-george solution setting idAttribute to another dummyId

searching for nested elements in mongodb, using api nodejs

At this moment I have in Node.JS API written a function
Board.find({ users : req.user._id})
It will find all documents where is id of user inside of array users,
for example
So this function will find this document.
{
"_id" : ObjectId("5a7f4b46f489dd236410d88a"),
"name" : "first",
"users" : [
ObjectId("5a1db9e8db97d318ac70715d")
]
}
What If I will change array of users in document for array objects id
{
"_id" : ObjectId("5a7f4b46f489dd236410d77c"),
"name" : "second",
"users" : [
{ _id : ObjectId("5a1db9e8db97d318ac70715d") }
]
}
How to find now this document in this situation, using only req.user._id which is saved inside object of users[]?
we can find it somehow now or not??
You just need to change it as : Board.find({ 'users._id' : req.user._id})
You could also use:
db.collection_name.find( { "user": { "_id" : req.user._id } } )

Categories