How do I find the most recent document in a MongoCollection? Currently I'm doing the following, but it seems to be returning the same value regardless:
_collection.FindAllAs<Game>().SetSortOrder(SortBy.Descending("When")).FirstOrDefault<Game>();
The documents are structured in pseudocode as follows:
Game
{
DateTime When;
List<Score> Scores;
...other variables...
}
The games are always stored sequentially via Update.PushWrapped<Score>(Score s)
How could I improve this?
One possible solution is to create a collection that stores the last inserted _id value of your collections and query for this value when you need to get the newest document.
As I said, that is one possible solution, and I'm sure that it will works, but maybe is not the best solution, it depends on your documents structure, etc.
I use this solution to do autoinc fields.
Related
Consider the following data
I am trying to update the property name from givenName to PetName. Below are the things I tried.
Option 1:
List<PatchOperation> patchOperations = new List<PatchOperation>();
dynamic data = new
{
PetName= "Dummy"
};
//Remove the 0th element from the pet array
patchOperations.Add(PatchOperation.Remove("/children/0/pets/0"));
//insert the new entity
patchOperations.Add(PatchOperation.Add<dynamic>("/children/0/pets/0", data));
await Container.PatchItemAsync<dynamic>("AndersenFamily", new
PartitionKey("AndersenFamily"), patchOperations);
This works on the first element (as I have specified the index as 0).
But I couldn't find a way to update all the elements in the array. Something like /children/*/pets (I get an error "Invalid navigation for array(*)").
Option 2:
Read all the data from the database, remove the existing pets and upload the new object with the property PetName. But I guess it will take lot of time to loop through all the objects and make these changes.
Can someone suggest a better solution or a way to fix the partial updates so that it updates all the elements in the array?
The actual dataset that I am working on is huge and has more nested arrays.
Yes you are right, Current version of Patch does not support patching nested array. You need to know the index in order to replace/add values as you mentioned in the first question.
One way to think about this would be to write your own logic to replace the keys , there are libraries available in dotnet and then using the bulk insert using the SDK to insert those documents.
I've been using guid's to identify elements in an xml document for editing. It seems that guid's are a lot more space than just an id field. In sql there is auto increment. Is there something similar or a decent way to auto increment for xml elements in Linq to XML?
The only constraint may be that once a number is used it cannot be used again.
Thanks.
I don't know what the "best" way is, but I'd think using a GUID would be a sure-fire way of getting a unique value for your ID field.
If you wanted an alternative method that uses a smaller number, you could try checking the file each time prior to inserting, and getting the next available ID that's one larger than the previous:
private int GenerateNextId()
{
var file = XDocument.Load("yourFile.xml"); // or pass an XDocument in
// so you don't have to reload it
return file.Descendants("SomeElement")
.OrderByDescending(x => Convert.ToInt32(x.Attribute("ElementId").Value))
.Select(x => Convert.ToInt32(x.Attribute("ElementId").Value))
.FirstOrDefault() + 1;
}
This is just posted as an alternative. I don't know how efficient this is as your XML grows in size. YMMV
If you decide to keep using the GUID, there are ways to shorten it, such as this SO post:
Convert.ToBase64String(Guid.NewGuid().ToByteArray());
I tried it out - the generated ID is nearly cut in half:
0b427c5a-1541-4cb4-8995-4e67dac61654
WnxCC0EVtEyJlU5n2sYWVA==
d1205a49-f64b-4418-8449-b1cd52f06624
SVog0Uv2GESESbHNUvBmJA==
I agree with #GrantWinney that GUIDs are a surefire way to get unique IDs.
However, you can also use DateTime.Now.ToFileTimeUtc();. It's not not guaranteed to be unique, though, like GUIDs: e.g. computers in different timezones adding XML records using this method, or even different computers in the same office.
If I remember correctly the ObjectId of a MongoDB document contains the timestamp of its creation. What would be the best way to update only the most recent document in a collection?
So say that I have a bunch of game documents and every so often a new document is created and every score should be saved to the most recent game, not to the previous games. I would like to do this in order to not store the game object in memory.
I've tried a couple of things and I couldn't make it in single operation. However, you don't need to store whole game object in memory. You can just ask for the latest _id. Something like this (shell pseudo syntax).
var last_id = db.games.find({}, {_id: 1}).sort({_id: -1}).limit(1);
db.games.update({_id: last_id}, {$inc: {score: 1}});
Update:
Okay, I should probably go to sleep now. Of course, it can be done using findAndModify. Here's JS code.
db.runCommand({findAndModify: 'games',
sort: {_id: -1},
update: {$inc: {score: 1}}})
Looking for help querying MongoDB for the latest inserted documents, to be run on a minute-to-minute basis.
Thilo had the gist.
If you need to get the most recently inserted "top level documents" (those you have table/collections of) you can use either ObjectId values since they are timestamped, or you can add a timestamp field to the document itself.
If you need to timestamp embedded documents (ex. Items in an Order) then you would not be able to use ObjectIds as your embedded collection are not "top level documents".
I'm not sure how accurate you need to be, but you may want to look into the issue of how records get inserted, as the timestamps may not always match the "real order" the items were submitted...
Also, look in to seeing if the timestamp on the ObjectId of top-level documents is altered when updated (a new item to an embedded collection) as that would affect things too.
Bottom line, when in doubt, add timestamp fields and write queries for them.
Asp.NET - C#.NET
I need a advice regarding a design problem below:
I'll receive everyday XML files. It changes the quantity e.g. yesterday 10 XML files received, today XML 56 files received and maybe tomorrow 161 XML files etc.
There are 12 types (12 XSD)... and in the top there is a attribute called FormType e.g. FormType="1", FormType="2" , FormType="12" etc. up to 12 formtypes.
All of them have common fields like Name, adres, Phone.
But e.g. FormType=1 is for Construction, FormType=2 is for IT, FormType 3=Hospital, Formtype=4 is for Advertisement etc. etc.
As I said all of them have common attributes.
Requirements:
Need a search screen so the user can do search on these XML contents. But I don't have any clue how to approach this. e.g. Search the text in some attributes for the xml's received from Date_From and Date_To.
Problem:
I've heard about putting the XML's in a Binary field and do XPATH query or whatever but don't know the word's to search on google.
I was thinking to create a big database.table and read all XML's and put in the Database Table. But the issue is some xml attributes are very huge like 2-3 pages. and the same attributes in other XML file are empty..
So creating NVARCHAR(MAX) for every XML attribute and putting them in table.field.... After some period my DATABASE will be a big big monster...
Can someone advice what is the best approach to handle this issue?
I'm not 100% sure I understand your problem. I'm guessing that the query's supposed to return individual XML documents that meet some kind of user-specified criteria.
In that event, my starting point would probably be to implement a method for querying a single XML document, i.e. one that returns true if the document's a hit and false otherwise. In all likelihood, I'd make the query parameter an XPath query, but who knows? Here's a simple example:
public bool TestXml(XDocument d, string query)
{
return d.XPathSelectElements(query).Any();
}
Next, I need a store of XML documents to query. Where does that store live, and what form does it take? At a certain level, those are implementation details that my application doesn't care about. They could live in a database, or the file system. They could be cached in memory. I'd start by keeping it simple, something like:
public IEnumerable<XDocument> XmlDocuments()
{
DirectoryInfo di = new DirectoryInfo(XmlDirectoryPath);
foreach (FileInfo fi in di.GetFiles())
{
yield return XDocument.Load(fi.Filename);
}
}
Now I can get all of the documents that fulfill a request like this:
public IEnumerable<XDocument> GetDocuments(query)
{
return XmlDocuments.Where(x => TextXml(x, query));
}
The thing that jumps out at me when I look at this problem: I have to parse my documents into XDocument objects to query them. That's going to happen whether they live in a database or the file system. (If I stick them in a database and write a stored procedure that does XPath queries, as someone suggested, I'm still parsing all of the XML every time I execute a query; I've just moved all that work to the database server.)
That's a lot of I/O and CPU time that gets spent doing the exact same thing over and over again. If the volume of queries is anything other than tiny, I'd consider building a List<XDocument> the first time GetDocuments() is called and come up with a scheme of keeping that list in memory until new XML documents are received (or possibly updating it when new XML documents are received).