Remove in MongoDb chsarp fails when using the _id - mongodb

in a sample program removing items from the mongo db doesn't work when I want to use the id.
I assume the problem is that my class has a Id Property, but mongo uses an _id ?
So when I trigger the remove in the following code nothing changes. Using remove with a query which uses name or value everything works as expected and the item gets removed.
Any hint ?
MongoServer server = MongoServer.Create(#"mongodb://localhost/?safe=true");
server.Connect();
var db = server.GetDatabase("data");
var collection = db.GetCollection<Foo>("foo");
string id = Guid.NewGuid().ToString();
Foo a = new Foo();
a.Id = id;
a.name = "Boas";
a.Value = 1;
collection.Insert<Foo>(a);
Console.WriteLine(collection.Count()+ " items"); // Count is 1
collection.Remove(Query.EQ("_id",id));
Console.WriteLine(collection.Count() + " items"); // Count is still 1 :-( should be 0
Console.ReadLine();
Addition:
When I use the same query with Find() the item is found. So I don't understand why find does find the element and remove doesn't remove it.
collection.Find(Query.EQ("_id",id)).Count() // returns 1 element

I have done this over and over and it continually prints out 1 items and then 0 items. Are you sure your collection doesn't already have an item in it?
After your collection.Insert(a), add a collection.RemoveAll().

Related

How to use database data on Event OnBeforeCreate

I want to get the last data created on my database, more specifically the field called: "Saldo Atual" and after this get the form data field "Valor" and make a sum between this fields (the Old one "Saldo Atual" and the new "Valor") before create a new record and add this "Valor" and the sum of "Saldo Atual"+"Valor".
I don't know how to get the database last record
var saldoAtual =
record.saldoAtual = saldoAtual + record.valor;
And I want to know if the second line it's correct to save the sum of "Saldo Atual"+"Valor"
Based on my comment, I think that your records will need to have a Date_Created field. Then in your onBeforeCreate event the following script should work (this is untested, so you need to do your own testing):
var query = app.models.YourModelTheSameAsYourEventModel.newQuery();
query.sorting.Date_Created._descending();
query.limit = 1;
var lastrecord = query.run();
record.saldoAtual = lastrecord.saldoAtual + record.valor; //You may need to use lastrecord[0].saldoAtual
record.Created_Date = new Date();
Try that and do some testing to see if this yields your desired output.

using email addresses as keys in firestore

I want to create "invitations" based on email addresses so that when a user with that email would arrive to the system his invitations would already be waiting for him.
so I wanted to create an invitations collection with key based on groupId + '_' + invited_user_email but if the user is test#test.com this the .com is interpreted as a subkey :(
I tried groupId + '_' + invited_user_email.replace(/[.]/g,'\\.') but it did not help either.
What am I missing? Is there no way to include a '.' in a firestore document's ID ?
EDIT:
per Doug Stevenson's request here is the code I use now:
var invitedUserEmailAsKey=invitedUserEmail.replace(/[.]/g,'\\.')
var batch = db.batch();
var groupRef = db.collection("groups").doc(groupId);
var invitationRef = db.collection("invitations").doc( groupRef.id + '_' + invitedUserEmailAsKey);
var groupUpdates = {};
groupUpdates['invited.' + invitedUserEmailAsKey + '.user_name'] = invitedUserName;
groupUpdates['merge'] = true;
batch.update(groupRef, groupUpdates);
The problems are with the updated document on the groups collection.
It ends up looking like this:
instead of having someone#gmail.com as a key
Using update() with "dot" in a key is interpreted as a nested field as documented here.
Notice that you're updating a document fields (groupRef) and not really doing anything with the "invitations" collection. I don't think that creating a new field on the group doc for every invitation is what you really mean to do.
As Dror mentioned, adding users with update() and a dot in the key won't work.
I use the set method with merge true:
addUserToGroup(id,email,type){
this.log("id",id,"email",email,"type",type);
let obj = {};
obj[email] = type;
this.angularFireStore.collection("Users").doc(id).set(obj, { merge: true }).then(() => {
this.log("addedUser",email);
}).catch((error) => {
this.log("failed to add user",error)
})
}
From the documentation: https://firebase.google.com/docs/firestore/manage-data/add-data#web-v8_1
"To create or overwrite a single document, use the set() method"
"If you're not sure whether the document exists, pass the option to merge the new data with any existing document to avoid overwriting entire documents."

Need to delete mongodb collection with prefix based name

I have number of collection in my mongodb.
The collections names are like aaa_123,aaa_345,aaa_ccc,mmm,nnn and etc...
Many collections name has prefixed with aaa_ and also other collection name also present, I need to delete only the collection names prefixed with aaa_ , but in manual I deleted like db.aaa_123.drop(), its take long time to delete collection , Is there anyway to delete all collections with prefixed aaa_ in mongodb?
Anyhelp appreciated..
First Get all collection in DB to one variable then loop through that variable and check for that name in collection. If that check condition satisfies delete that collection. Check below for code sample
var collectionNames = db.getCollectionNames();
for(var i = 0, len = collectionNames.length; i < len ; i++){
var collectionName = collectionNames[i];
if(collectionName.indexOf('aaa_') == 0){
db[collectionName].drop()
}
}
Hope this helps

linq nested query conditional order by

I have a parent query with sub query return child ,
what i need to sort child query according to one property in parent.
here is sudo code:
from menu in db.Menus
orderby menu.Order
select new
{
Title= menu.Title,
OrderNumber = menu.Order,
data = (from menuItem in menu.Items
let g = Guid.NewGuid()
orderby g
select new
{
id = worker.ID,
Title = worker.JobTitle
})
.Take(4)
};
that works ok,But what i need to sort some menu in random(NewGuid) and sort others with their item priority some thing like it:
let g = Guid.NewGuid()
orderby menu.ISRandom ? g: menuItem.Order
But it give error about mismatch guid and int.What's the soloution?
second:How can i replace take(4) with take(menu.size)?
thank's
You can solve the ordering problem by adding ToString():
let g = Guid.NewGuid().ToString()
orderbymenu.ISRandom ? g : menuItem.Order.ToString()
Using Take(someProperty) isn't allowed in an EF LINQ query. This is because the take is translated into a TOP(x) clause, which can't possibly refer to a column in the SQL result. You can only do this afterwards, after pulling the results into memory without Take (or taking some reasonable fixed maximum).
It seems you want to read four records from menu.Items at random.
I think you'd be way better off just reading all the items, and then doing the random selection later in code in memory.

.Include in following query does not include really

var diaryEntries = (from entry in repository.GetQuery<OnlineDiary.Internal.Model.DiaryEntry>()
.Include("DiaryEntryGradeChangeLog")
.Include("DiaryEntryAction")
join diary in repository.GetQuery<OnlineDiary.Internal.Model.OnlineDiary>()
on entry.DiaryId equals diary.Id
group entry
by diary
into diaryEntriesGroup
select new { Diary = diaryEntriesGroup.Key,
DiaryEntry = diaryEntriesGroup.OrderByDescending(diaryEntry => diaryEntry.DateModified).FirstOrDefault(),
});
This query does not include "DiaryEntryGradeChangeLog" and "DiaryEntryAction" navigation properties, what is wrong in this query?
I have removed join from the query and corrected as per below, and still it populates nothing
var diaryEntries = from entry in repository.GetQuery<OnlineDiary.Internal.Model.DiaryEntry>()
.Include("DiaryEntryGradeChangeLog").Include("DiaryEntryAction")
.Where(e => 1 == 1)
group entry
by entry.OnlineDiary
into diaryEntryGroups
select
new { DiaryEntry = diaryEntryGroups.OrderByDescending(diaryEntry => diaryEntry.DateModified).FirstOrDefault() };
It will not. Include works only if the shape of the query does not change (by design). If you use this query it will work because the shape of the query is still same (OnlineDiary.Internal.Model.DiaryEntry):
var diaryEntries = (from entry in repository.GetQuery<OnlineDiary.Internal.Model.DiaryEntry>()
.Include("DiaryEntryGradeChangeLog")
.Include("DiaryEntryAction");
But once you use manual join, grouping or projection (select new { }) you have changed the shape of the query and all Include calls are skipped.
Edit:
You must use something like this (untested) to get related data:
var diaryEntries = from entry in repository.GetQuery<OnlineDiary.Internal.Model.DiaryEntry>()
group entry by entry.OnlineDiary into diaryEntryGroups
let data = diaryEntryGroups.OrderByDescending(diaryEntry => diaryEntry.DateModified).FirstOrDefault()
select new {
DiaryEntry = data,
GradeChangeLog = data.DiaryEntryGradeChangeLog,
Action = data.DiaryEntryAction
};
or any similar query where you manually populate property for relation in projection to anonymous or unmapped type.