i'm new to mongo and could use help with this query.
My objects can look like this.
device = {
stuff:'otherstuff',
read: {
moreStuff: 'stuff',
timestamp: 'some date'
}
}
or this
device = {
stuff:'otherstuff',
}
I want to write a query that will update device.read if read doesn't exist or if the new timestamp is greater than the current read.timestamp. Is there a way to update this in place? Or do I need to have logic before hand that determines if the timestamp is greater?
Thanks for any help,
use your variables and set variables but this is the base concept
db.collaction.update(
{
$or:[
read:{$exists: false},
"read.timestamp":{$gt:timestamp}
]}
,{set:{"read.timestamp":timestamp}}
)
Related
Now I'd like to save my json data into mongoose but the duplicate value had to be filtered.
my_json = [
{"name":"michael","age":21,"sports":"basketball"},
{"name":"nick","age":31,"sports":"golf"},
{"name":"joan","age":41,"sports":"soccer"},
{"name":"henry","age":51,"sports":"baseball"},
{"name":"joe","age":61,"sports":"dance"},
];
Database data is :
{
"name":"joan","age":41,"sports":"soccer"
}
Is there some specific method to avoid duplicate data insert to mongoose directly? It might be saved 4 of values except "joan" value.
Once I suppose to try to use "for statement", it was fine.
However I just want to make a simple code for that what could happen in a variety possible code.
for(var i = 0; i < my_json.length; i++){
// to check out duplicate value
db.json_model.count({"name":my_json[i].name}, function(err, cat){
if(cat.length == 0){
my_json_vo.savePost(function(err) {
});
}
})
};
As you see I need to use count method whether the value is duplicated or not. I don't want to use count method but make it more simple..
Could you give me an advice for that?
You can mark field as unique in mongoose schema:
var schema = new Schema({
name: {type: String, required: true, unique: true}
//...
});
Also, you can add unique index for name field into your database:
db.js_model.createIndex( {"name": 1}, { unique: true, background: true } );
then, if new entity with the same name will be asked to save - mongo won't save it, and respond an error.
In Addition to #Alex answer about adding unique key on the name field.
You can use insertMany() method with ordered parameter set to
false. Like this...
let my_json = [
{"name":"michael","age":21,"sports":"basketball"},
{"name":"nick","age":31,"sports":"golf"},
{"name":"joan","age":41,"sports":"soccer"},
{"name":"henry","age":51,"sports":"baseball"},
{"name":"joe","age":61,"sports":"dance"},
];
User.insertMany(my_json ,{ordered :false});
This query will successfully run and insert unique documents, And also
produces error later after successful insertion. So You will come to
know that there were duplicate records But now in the database, all
records are unique.
Reference InsertMany with ordered parameter
I have an array of objects and I want to store them in a collection using only one I/O operation if it's possible. If any document already exists in the collection I want to replace it, or insert it otherwise.
These are the solutions that I found, but doesn't work exactly as I want:
insertMany(): this doesn't replace the document that already exists, but throws exception instead (This is what I found in the Mongodb documentation, but I don't know if it's the same as mongoose).
update() or updateMany() with upsert = true: this doesn't help me as well, because here I have to do the same updates to all the to stored documents.
There is no replaceMany() in mongodb or mongoose.
Is there anyone how knows any optimal way to do replaceMany using mongoose and node.js
There is bulkWrite (https://docs.mongodb.com/manual/reference/method/db.collection.bulkWrite/), which makes it possible to execute multiple operations at once. In your case, you can use it to perform multiple replaceOne operations with upsert. The code below shows how you can do it with Mongoose:
// Assuming *data* is an array of documents that you want to insert (or replace)
const bulkData = data.map(item => (
{
replaceOne: {
upsert: true,
filter: {
// Filter specification. You must provide a field that
// identifies *item*
},
replacement: item
}
}
));
db.bulkWrite(bulkData);
You need to query like this:
db.getCollection('hotspot').update({
/Your Condition/
}, {
$set: {
"New Key": "Value"
}
}, {
multi: true,
upsert: true
});
It fulfils your requirements..!!!
I am trying to figure out the most efficient way to find and populate documents some of which have references to another collection and some don't.
Example:
var collectionA={
{
"topic":"TopicA",
"text";"TextA")
},
{
"topic":"Topic1",
"text":"Text1"}
}
}
var collectionB={
{
"topic":"TopicB",
"text":"TextB"
"reference":["id","id"]
},
{
"topic":"Topic2",
"text":"Text2"
"reference":[]
}
}
and I have a request as follows which allows me to identify the documents I want:
req.body={"topic":["TopicA","TopicB"]}
What is the most efficient way to find the relevant documents and populate them to provide a fully populated result, in the fewest number of database calls as possible:
{"topic":"TopicA","text":"TextA"},
{"topic":"TopicB","text":"TextB","reference":[{populated document}
{populated document}]},
I am trying to use something like:
collections.find({"topic": $in req.body.top}, function(err,result){
collections.populate(result,{path:'references'}, function (err,result){
//do something
});
})
Is this on the right track?
Your help is greatly appreciated.
In order to reference other documents in mongoose you need to use Population.
If you want to reference a topic by id you would need to have something like the following in your schema: { type: Schema.Types.ObjectId, ref: 'collectionA' }
i would like to have a function in my controller to get data based on time range. First, i have all the data in mongodb, there is a attribute ModifiedTime as string looks like 2015-02-25T17:17:33Z. Second, i define the model in sails with ModifiedTime:
{ type: 'datetime', columnName: 'ModifiedTime' }
In the model.js, I set schema: true. Then in my controller, i try to use
User.find({ModifiedTime : {'<=' : new Date('2015-03-18T00:00:00Z')}}).exec(function(err,st){
if (err) return res(err);
if (!st) return res(new Error('Invalid ModifiedTime.'));
return res.json(st);
} );
But i get nothing, see always [] in the browse. I used waterline http://localhost:1337/User to check the data in browse. i can see all the data from mongodb. The strange thing is, i see something like ModifiedTime": "2015-02-18T17:36:53Z. so, for me, it looks like the ModifiedTime in sails is still a string, am i right? but i set the type as datetime in the model. I hope, it could transfer the string of mongodb to datetime in background, won't it? Please give some advise. i spend already too much time for that :(
thank you very much!
WJS
You're right / wrong.
In your DB you state the datetime is a string. If it is already a string then you can't set it to be a date in your sails model. You should simply compare two strings instead of transforming 2015-03-18T00:00:00Z into a date.
User.find({ModifiedTime : {'<=' : '2015-03-18T00:00:00Z'}}).exec(function(err,st){
if (err) return res(err);
if (!st) return res(new Error('Invalid ModifiedTime.'));
return res.json(st);
} );
If you truley want to use Date/Time then you must go through your original data and change modified time to a date/time object.
I want to record user events to my mongodb collection. Is it possible to set up a simple query to only store the last recorded time stamp for an event for an arbitrary, dynamically changing set of events (so when a new event is received, it is inserted)?
I know the following doesn't work, but i wanted to give an idea of what I'm thinking:
uievents.update({_id:id},{
$set: {userName:user,
("events."+eventName): {
eventName: eventName,
serverTime: curTime,
browserTime: btime,
value: value
}},{$upsert:true});
Easiest way to do his is really simple:
query = {$set: {}}
query["$set"]["event."+eventName] = {
eventName: eventName,
serverTime: curTime,
browserTime: btime,
value: value
}
uievents.update({_id:id},query,{$upsert:true});