How do I create a document with subdocument in MongoDB with C# - c#

I want to create a nested document with c# in mongodb.
My Code Looks like this
var documnt = new BsonDocument
{
{ "name","test1"},
{ "nachname","test5"},
{ "age","test2"},
{ "wohnort","test3"},
{"test","test4" }
};
collection.InsertOneAsync(documnt);
Console.Read();`
how can i add a subdocument to Wohnort?

Ive found the answer by myself
var documnt = new BsonDocument
{
{ "name","test1"},
{ "nachname","test5"},
{ "age","test2"},
{ "wohnort", new BsonArray
{
new BsonDocument {{"test1","test1"}}}
}
};
collection.InsertMany(documnt);
Console.Read();

Related

Method inside an array in C#

I just got in contact with C# and I was wondering if it's possible to call a method inside an array. I have to say that I'm working with NoSQL database (mongodb).
This is mi code, and I want to call data() method inside that JSON.
static void Main(string[] args)
{
MongoClient client = new MongoClient();
var db = client.GetDatabase("test");
var collection = db.GetCollection<BsonDocument>("collection");
var document = new BsonDocument
{
{ "date", 10/04/2018 },
{ "data", data() }
};
collection.InsertOneAsync(document);
Console.Read();
}
static void data()
{
for (int i = 1; i <= 50; i++)
{
var data = new BsonDocument
{
{ "magnitude"+i, new BsonDocument{
{ "value", 5 }
} }
};
}
}
EDIT: Basically, what I'm trying to create with C# is this json below. I already did it with PHP and now, I'm trying to do it with C#.
{
"_id" : ObjectId("5abb735eb57dce214009035a"),
"date" : 1262300400,
"data" : {
"magnitude1" : {
"value" : 60
},
"magnitude2" : {
"value" : 38
},
"magnitude3" : {
"value" : 200
},
"magnitude4" : {
"value" : 62
},
"magnitude5" : {
"value" : 153
},
"magnitude6" : {
"value" : 176
},
"magnitude7" : {
"value" : 185
},
"magnitude8" : {
"value" : 168
},
.
.
.
You can use methods to gather data but I'm not sure exactly how you're asking it. Related to the code example I'll just give a simple run down, which is basic programming in general, not just C#.
You can write methods that return void or that return a variable of some type (at a minimum).
//Returns void
public void DoSomething()
{
//Do some work
return;
}
//Returns int
public int GetSomething()
{
int result = 100;
return result;
}
When you have methods that return data you can use them as you would a variable; just remember the method will execute every time it's called so it's often best to save the data to a variable. But for your example you can do something like this.
//other code ommitted
var document = new BsonDocument
{
{ "date", 10/04/2018 },
{ "data", getDocuments() }
};
//remaining code omitted
static List<BsonDocument> getDocuments()
{
var documents = new List<BsonDocument>();
for (int i = 1; i <= 50; i++)
{
var document = new BsonDocument
{
{ "magnitude" + i, new BsonDocument { { "value", 5 } } }
};
documents.Add(document);
}
return documents;
}
Now I modified the data() method to return a list of documents and changed the naming to match it but I'm not sure what you wanted to do with the method. That was my best assumption of what you were trying to accomplish by looking at your code so feel free to ignore all of it if it's wrong.
I've could solve it thanks to #Michael .Code below in case helps to anyone.
static void Main(string[] args)
{
MongoClient client = new MongoClient();
var db = client.GetDatabase("test");
var collection = db.GetCollection<BsonDocument>("Collection");
var document = new BsonDocument
{
{ "date", 10/04/2018 },
{ "data", new BsonDocument{ getDocuments() } }
};
collection.InsertOneAsync(document);
Console.Read();
}
static BsonDocument getDocuments()
{
var documents = new BsonDocument();
for (int i = 1; i <= 5; i++)
{
var document = new BsonDocument
{
{ "magnitude" + i, new BsonDocument { { "value", 5 } } }
};
documents.AddRange(document);
}
return documents;
}

How to get a Sitecore item from a fake site

In a unittest I am using Sitecore.FakeDb.
I have extended the sample to add the fakeSite with a rootPath, which gets set.
If I try to retrieve the rootItem with Context.Site.GetItem(rootPath) it returns null.
[Test]
public void FakeSite()
{
// create a fake site context
var fakeSite = new Sitecore.FakeDb.Sites.FakeSiteContext(
new Sitecore.Collections.StringDictionary
{
{ "name", "website" }, { "database", "web" }, { "rootPath", "/sitecore/content/NL" }
});
// switch the context site
using (new Sitecore.Sites.SiteContextSwitcher(fakeSite))
{
var rootItem = Context.Site.Database.GetItem(Context.Site.RootPath); // returns null
Assert.IsNotNull(rootItem);
Assert.AreEqual("website", Sitecore.Context.Site.Name);
Assert.AreEqual("master", Sitecore.Context.Site.Database.Name);
}
}
What am I missing?
You need to add fake item to your fake db first.
See sample code from github here:
public void HowToCreateSimpleItem()
{
using (Sitecore.FakeDb.Db db = new Sitecore.FakeDb.Db
{
new Sitecore.FakeDb.DbItem("Home") { { "Title", "Welcome!" } }
})
{
Sitecore.Data.Items.Item home = db.GetItem("/sitecore/content/home");
Xunit.Assert.Equal("Welcome!", home["Title"]);
}
}
public void HowToCreateHierarchyOfItems()
{
using (Sitecore.FakeDb.Db db = new Sitecore.FakeDb.Db
{
new Sitecore.FakeDb.DbItem("Articles")
{
new Sitecore.FakeDb.DbItem("Getting Started"),
new Sitecore.FakeDb.DbItem("Troubleshooting")
}
})
{
Sitecore.Data.Items.Item articles =
db.GetItem("/sitecore/content/Articles");
Xunit.Assert.NotNull(articles.Children["Getting Started"]);
Xunit.Assert.NotNull(articles.Children["Troubleshooting"]);
}
}
https://github.com/sergeyshushlyapin/Sitecore.FakeDb/wiki/Creating-a-Simple-Item
https://github.com/sergeyshushlyapin/Sitecore.FakeDb/wiki/Creating-a-Hierarchy-of-Items
As #Marek said, I didn't create an item, just set the rootPath to which item it should point.
This is the working test.
[Test]
public void FakeSite()
{
using (Db db = new Db("web")
{
new DbItem("NL") { { "Title", "NL Site" } }
})
{
Item siteItem = db.GetItem("/sitecore/content/NL");
// create a fake site context
var fakeSite = new Sitecore.FakeDb.Sites.FakeSiteContext(
new Sitecore.Collections.StringDictionary
{
{ "name", "website" }, { "database", "web" }, { "rootPath", "/sitecore/content/NL" }
});
// switch the context site
using (new Sitecore.Sites.SiteContextSwitcher(fakeSite))
{
Assert.AreEqual("website", Sitecore.Context.Site.Name);
Assert.AreEqual("web", Sitecore.Context.Site.Database.Name);
var rootItem = Context.Site.Database.GetItem(Context.Site.RootPath);
Assert.IsNotNull(rootItem);
}
}
}
Although I realize that Site means the CM/CD site. Not the MultiSite I was looking for.

Turn BsonArray into List<T>

I've been working at this and have managed to get the json parsed into a C# object. Now the next step was to parse a json array into a List. I have managed to get the job done but I'm pretty sure there is a better way to convert from BsonArray to a List
using (StreamReader file = File.OpenText(filename))
{
try
{
//first up convert to bson
var jsonSampleData = file.ReadToEnd();
//var bsonSampleData = BsonDocument.Parse(jsonSampleData);
//this would be for a single BSOnDocument
var bsonSampleData = BsonSerializer.Deserialize<BsonArray>(jsonSampleData);
var x = bsonSampleData.ToList();
List<ThePlan> lst = new List<ThePlan>();
foreach (var doc in x)
{
var t = BsonSerializer.Deserialize<ThePlan>(doc.AsBsonDocument);
lst.Add(t);
}
}
catch (Exception ex)
{
throw;
}
Edit-Additional Information
To be clear what I am needing to accomplish is taking the given json document and rehydrate it to List. This is further complicated by my being new to mongo and T is a mongo entity representation.
As Andrei pointed out it works fine:
using (StreamReader file = File.OpenText(filename))
{
var jsonSampleData = file.ReadToEnd();
_thePlan = BsonSerializer.Deserialize<List<ThePlan>>(jsonSampleData);
}
Thinking about my struggles yesterday I think it actually had to do with my json where on my early attempts it looked like this:
{
"_id": "57509afbc6b48d3f33b2dfcd",
...
}
In the process of figuring it all out my json matured to:
{
"_id": { "$oid": "57509afbc6b48d3f33b2dfcd" },
.....
}
The troubles I was having with BsonSerializer was likely my bad json and once that was worked out I wasn't astute enough to go back to the BsonSerielizer and try again.
Either go strongly typed all the way or not typed at all.
strongly typed
Assuming these are your types:
public class BaseObject {
[BsonId] public ObjectId id { get; set; }
[BsonElement("plans")] public List<ThePlan> Plans { get; set; }
}
public class ThePlan {
[BsonElement("i")] public int Integer { get; set; }
[BsonElement("s")] public string String { get; set; }
}
and these test utilities:
void ToJsonTyped(BaseObject bo)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
using (BsonWriter bw = new JsonWriter(tw))
{
BsonSerializer.Serialize<BaseObject>(bw, bo);
}
string jsonObject = sb.ToString();
BaseObject bo2 = BsonSerializer.Deserialize<BaseObject>(jsonObject);
Assert.AreEqual(bo, bo2);
}
void ToBsonTyped(BaseObject bo)
{
byte[] bsonObject = null;
using (var ms = new MemoryStream())
using (BsonWriter bw = new BsonBinaryWriter(ms))
{
BsonSerializer.Serialize<BaseObject>(bw, bo);
bsonObject = ms.ToArray();
}
BaseObject bo1 = BsonSerializer.Deserialize<BaseObject>(bsonObject);
Assert.AreEqual (bo, bo1);
}
you can test:
BaseObject bo = new BaseObject() {
Plans = new List<ThePlan>() {
new ThePlan() {Integer=1, String="one" },
new ThePlan() {Integer=2, String="two" },
new ThePlan() {Integer=3, String="three" } } };
ToBsonTyped(bo);
ToJsonTyped(bo);
not typed at all, combo of BsonDocument and BsonArray
test:
BsonDocument doc = new BsonDocument();
var bsonArray = new BsonArray();
bsonArray.Add(new BsonDocument("one", 1));
bsonArray.Add(new BsonDocument("two", 2));
bsonArray.Add(new BsonDocument("three", 3));
doc.Add( new BsonElement("plans", bsonArray));
ToBsonUnTyped(doc);
ToJsonUnTyped(doc);
test utils:
void ToBsonUnTyped(BsonDocument doc) {
byte[] bsonObject = null;
using (var ms = new MemoryStream())
using (BsonWriter bw = new BsonBinaryWriter(ms))
{
BsonSerializer.Serialize<BsonDocument>(bw, doc);
bsonObject = ms.ToArray();
}
BsonDocument docActual = BsonSerializer.Deserialize<BsonDocument>(bsonObject);
Assert.AreEqual (doc, docActual);
}
void ToJsonUnTyped(BsonDocument doc)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
using (BsonWriter bw = new JsonWriter(tw))
{
BsonSerializer.Serialize<BsonDocument>(bw, doc);
}
string jsonObject = sb.ToString();
BsonDocument doc2 = BsonSerializer.Deserialize<BsonDocument>(jsonObject);
Assert.AreEqual(doc, doc2);
}

MongoDB c# using new driver

I know I may sound to you guys like a total nob but I am.
I am trying to use the mongodb driver in c#. Try to do something like add a record.
I learned today all basic mongodb queries and even tried it with robomongo.
But i don't understand how to use it in c#?
how to call it from the main function??
this is the code I wrote (trying to use mongodb website tutorial):
what is await? what is Task? what does it mean and how to make it work?
Thank you a lot for helping me.
class Program
{
protected static IMongoClient _client;
protected static IMongoDatabase _database;
public static void Main()
{
_client = new MongoClient();
_database = _client.GetDatabase("test");
Task simpleTask = Tasky();
}
public async Task Tasky()
{
var document = new BsonDocument
{
{ "address" , new BsonDocument
{
{ "street", "2 Avenue" },
{ "zipcode", "10075" },
{ "building", "1480" },
{ "coord", new BsonArray { 73.9557413, 40.7720266 } }
}
},
{ "borough", "Manhattan" },
{ "cuisine", "Italian" },
{ "grades", new BsonArray
{
new BsonDocument
{
{ "date", new DateTime(2014, 10, 1, 0, 0, 0, DateTimeKind.Utc) },
{ "grade", "A" },
{ "score", 11 }
},
new BsonDocument
{
{ "date", new DateTime(2014, 1, 6, 0, 0, 0, DateTimeKind.Utc) },
{ "grade", "B" },
{ "score", 17 }
}
}
},
{ "name", "Vella" },
{ "restaurant_id", "41704620" }
};
var collection = _database.GetCollection<BsonDocument>("restaurants");
await collection.InsertOneAsync(document);
}
}
Try to understand simpler version, then read about async/await. Add some documents to your collection using mongo shell and try this:
var collection = new MongoClient("mongodb://localhost").GetServer()
.GetDatabase("your_db").GetCollection<BsonDocument>("your_collection");
var cursor = collection.FindAll();
foreach(var doc in cursor) {
Console.WriteLine(doc);
}
cursor is used to get documents one by one.

MongoDB c# create role?

I'm trying to create a role with the c# driver.
Can anyone please tell me how to do this?
I tried several things like this:
var command = new CommandDocument(
new BsonDocument
{
{ "createRole", "Testentity_read" },
{ "privileges", new BsonArray(new BsonDocument
{
{
"resource", new BsonDocument
{
{"db", "MyDb"},
{"collection", "Testentity"}
}
},
{
"actions", new BsonArray {"read"}
}
})},
{ "roles", new BsonArray()}
}
);
var result = _database.RunCommand(command);
but always getting this exception:
".NET type MongoDB.Bson.BsonElement cannot be mapped to a BsonValue."
I found out how to create a role from C#-driver.
var command = new CommandDocument
{
{
"createRole", "Testentity_find"
},
{
"privileges", new BsonArray
{
new BsonDocument
{
{
"resource", new BsonDocument
{
{"db", "MyDb"},
{"collection", "Testentity"}
}
},
{
"actions", new BsonArray {"find"}
}
}
}
},
{ "roles", new BsonArray()}
};

Categories

Resources