I have a collection which contains documents like:
{
field1: {subfield1:{ssfield1:5,ssfield2:6},subfield2:6},
field2: 1,
...
}
I'd like to fetch only the subfield, but I'm not sure how to get it querying from csharp (it doesn't seem to return the bsondocument within the bsondocument).
Any help?
I tried this:
String c = "mongodb://"+myip;
MongoServer server = MongoServer.Create(c);
MongoDatabase db = server.GetDatabase(mydb);
var collection = db.GetCollection(col);
string[] fields = new string[] { "field1" };
MongoCursor cursor = collection.Find().SetFields(fields);
but it seems to return
{subfield2:6}
I created a collection with one document very similar to your sample document:
> db.test.find().pretty()
{
"_id" : ObjectId("518ac1aa92f1c388279a9979"),
"field1" : {
"subfield1" : {
"ssfield1" : 5,
"ssfield2" : 6
},
"subfield2" : 6
},
"field2" : 1
}
>
Before showing the result I got when I attempted to reproduce your C# code, let's look at the same query in the MongoDB shell:
> db.test.find({}, { field1 : 1 }).pretty()
{
"_id" : ObjectId("518ac1aa92f1c388279a9979"),
"field1" : {
"subfield1" : {
"ssfield1" : 5,
"ssfield2" : 6
},
"subfield2" : 6
}
}
>
There are several things to notice here:
By default the server always returns the _id field
field1 was the only other field returned (just what we asked for)
subfield2 was returned because it's embedded in field1
I used slightly different C# code from yours to test:
foreach (var document in collection.FindAll().SetFields("field1"))
{
Console.WriteLine(document.ToJson(new JsonWriterSettings { Indent = true }));
}
And the output I got from that loop was:
{
"_id" : ObjectId("518ac1aa92f1c388279a9979"),
"field1" : {
"subfield1" : {
"ssfield1" : 5.0,
"ssfield2" : 6.0
},
"subfield2" : 6.0
}
}
which is essentially identical to the output from the MongoDB shell.
Let me know if you have any further questions.
Related
I have some query written in c# using mongoDb driver.
var project = new BsonDocument
{
{ "Id" , "$asCompany._id"}, { "Code" , "$asCompany.Code"}, { "Name" , "$asCompany.Name"}, { "Address" , "$asCompany.Address"},
{ "ConcurrencyId" , new BsonDocument{ { "$concat", new BsonArray{ "1_3_", "$asCompany._id" } } } }
};
The above statement is using as project in the below code.
var joinresult3 = userCollection.Aggregate()
.Match(user => user.Id == userId)
.Lookup("Division", "Divisions.DivisionId", "_id", "asDivisons")
.Lookup("Company", "asDivisons.CompanyId", "_id", "asCompany")
.Project(project).ToList();
Ok, so the statement I wrote for projection is generating the following server side code. Which is seems to be correct.
{ "$project" : { "Id" : "$asCompany._id", "Code" : "$asCompany.Code", "Name" : "$asCompany.Name", "Address" : "$asCompany.Address", "ConcurrencyId" : { "$concat" : ["1_3_", "$asCompany._id"] } } }
But, the c# code is throwing following exception.
Command aggregate failed: $concat only supports strings, not array.
Thanks, in advance.
I have a JSON data (file attached). How can I parse it using C# using LitJSON? I am having trouble in deserialising it. Any help would be appreciated.
{
"vr-sessions" : {
"-KvDNAFD_BxlKEJ958eX" : {
"interview" : "Android",
"questions" : {
"-KvG7BuWu4eI52pq-6uH" : {
"playaudio" : "audio1",
"question" : "Why cannot you run standard Java bytecode on Android?"
},
"-KvG9rxQv5DWJa1EMnhi" : {
"playaudio" : "audio2",
"question" : "Where will you declare your activity so the system can access it?"
}
}
},
"-KvDNOE8YhVdgovxrzrN" : {
"interview" : "DevOps",
"questions" : {
"-KvMPd0v9BXnjYZxFm5Q" : {
"playaudio" : "audio3",
"question" : "Explain what is DevOps?"
},
"-KvMPi24OKeQTp8aJI0x" : {
"playaudio" : "audio4",
"question" : "What are the core operations of DevOps with application development and with infrastructure?"
},
"-KvMPqYxJunKp2ByLZKO" : {
"playaudio" : "audio5",
"question" : "Explain how “Infrastructure of code” is processed or executed in AWS?"
}
}
},
After adding a couple of missing braces and removing last comma, your json seems to be valid. However there's no way to declare a class or member starting with dash in C#. Not sure how LitJson would be able to map json values to a C# class if names don't match, unless you replace dashes before parsing the string with LitJson.
Workaround
In your Solution Explorer right click References and do Add Reference, then from Assemblies->Framework select System.Web.Extensions.
string jsonString = File.ReadAllText("json.txt");
dynamic json = new JavaScriptSerializer().Deserialize<dynamic>(jsonString);
Navigate to the value you're looking for
string interview = json["vr-sessions"]["-KvDNAFD_BxlKEJ958eX"]["interview"];
Variable interview gets value "Android" which is the same as doing this:
var sessions = json["vr-sessions"];
string interview = sessions["-KvDNAFD_BxlKEJ958eX"]["interview"];
If you don't know session names
Iterate to get question and playaudio values.
foreach (var session in json["vr-sessions"].Values)
{
foreach (var question in session["questions"].Values)
{
Console.WriteLine(question["question"]);
Console.WriteLine(question["playaudio"]);
}
}
Access to an element by position: let's say you want to iterate 0..N
var sessions = new List<dynamic>(json["vr-sessions"].Values);
Console.WriteLine(sessions[0]["interview"]);
This prints "Android" as the value of interview for session at position 0 is "Android".
I have documents like this:
/* 1 */
{
"_id" : ObjectId("573f3944a75c951d4d6aa65e"),
"Source" : "IGN",
"Country" : "US"
}
/* 2 */
{
"_id" : ObjectId("573f3d41a75c951d4d6aa65f"),
"Source" : "VG",
"Country" : "Norway"
}
/* 3 */
{
"_id" : ObjectId("573f4367a75c951d4d6aa660"),
"Source" : "NRK",
"Country" : "Norway"
}
/* 4 */
{
"_id" : ObjectId("573f4571a75c951d4d6aa661"),
"Source" : "VG",
"Country" : "Norway"
}
/* 5 */
{
"_id" : ObjectId("573f468da75c951d4d6aa662"),
"Source" : "IGN",
"Country" : "US"
}
And a list of sources like this:
list = ['VG', 'IGN']
I want to return only the documents with source equals 'IGN' or 'VG' (any of elements in list)
How can I do this with the official C# mongodb driver?
Assuming you are using MongoDB C# driver version 2.2, you can use FilterDefinitionBuilder class to filter out desired results.
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
... Your class and method declaration ...
IMongoClient client = new MongoClient ("mongodb://localhost:27017/test");
IMongoDatabase database = client.GetDatabase("test");
IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument> ("collection");
var filter = Builders<BsonDocument>.Filter.AnyIn ("Source", new[]{"VG", "IGN"});
var cursor = await collection.FindAsync (filter);
var docs = cursor.ToList();
docs will hold only those documents with source either VG or IGN. Based on your sample data, it will have 4 documents.
I'll recommend you to have a look at how to Find or Query Data with C# Driver
It's a bit late, but I had the same question as OP and actually the accepted answer is wrong. AnyIn is the correct filter if your database object itself contains an array where you want to search.
In OP's (and also in my) case, the simple In filter is the correct one to use:
var filter = Builders<BsonDocument>.Filter.In("Source", new[]{"VG", "IGN"});
or with lambda
var filter = Builders<BsonDocument>.Filter.In(o => o.Source, new[]{"VG", "IGN"});
I have this following query working on mongo shell as expected.
db.getCollection('personnels').update(
{
_id: ObjectId("55f6728b9d73a15807885de8"),
"Devices._id":ObjectId("55fa5f7ac9e7863a3836e331")
},
{
$pull:{ "Devices.$.DeviceCloudFolders": { "CloudFolderId": ObjectId("5615124b06275f072040c4f1")}}
}
);
And here is my document structure:
{
"_id" : ObjectId("55f6728b9d73a15807885de8"),
"FirstName" : "Tolga",
"Devices" : [
{
"_id" : ObjectId("55fa5f7ac9e7863a3836e331"),
"Name" : "tolga-laptop",
"DeviceCloudFolders" : [{
"AuthorityType" : 1,
"CloudFolderId" : ObjectId("55f96db5c9e7863a3836e310"),
"Status" : 1
}],
"Status" : 1
}
],
"Status" : 1
}
I need to use it in C# and couldn't figure out how.
I started with these lines:
var filter = Builders<Personnel>.Filter.And(
Builders<Personnel>.Filter.Eq("_id", ownerPersonnelId),
Builders<Personnel>.Filter.Eq("Devices._id", _id));
var update = Builders<Personnel>.Update.PullFilter("Devices.$.DeviceCloudFolders", /*couldn't figure out what goes here*/))
Personnels.FindOneAndUpdateAsync(filter, update);
I'm not sure, but you can try using this:
var update = Builders<Personnel>.Update.PullFilter(
"Devices.$.DeviceCloudFolders",
Builders<DeviceCloudFolder>.Filter.Eq("CloudFolderId", _cloudFolderId));
I have the following document in a mongodb collection
{
"_id" : "52bbd9bef2ba1f37f4f010c1",
"Name" : "Some Name",
"TypeId" : 1
}
I now want to edit this document using the c# driver
BsonDocument doc = BsonDocument.Parse(json);
IMongoQuery query = Query.And(Query.EQ("_id", doc["_id"]));
UpdateBuilder ub = MongoDB.Driver.Builders.Update.Set('Name', 'New Name');
WriteConcernResult updatedBook = _collection.Update(query, ub);
if (!updatedBook.UpdatedExisting)
{
// I always end here
}
It is also weird that the docs tell that _collection.Update(query, ub) should return a BsonDocument while they return a WriteConcernResult. Anyway if I use another property then _id I find the record.
It seems MongoDB is expecting a ObjectId() function wrapper around a ObjectId, isn't it? At least I need this in my tests while using MongoVUE.
Edit
If I try to find a record with this query
{
"_id" : "52bbd9bef2ba1f37f4f010c1"
}
I get nothing. If I use this
{
"_id" : ObjectId("52bbd9bef2ba1f37f4f010c1"),
}
it worked. So much for the Javascript way. AFAIK I have two ways to update a record with the native .net driver:
FindAndModifyResult
WriteConcernResult
But both ways expecting a BsonValue as value where ObjectId seems not to be a valid one...
So I tried using
IMongoQuery query = Query.And(Query.EQ("_id", doc["_id"]));
as described above but that is the same like
{
"_id" : "52bbd9bef2ba1f37f4f010c1"
}
So I wonder how to update a document by it's ObjectId?
When using the currently available Nuget published MongoDB driver for .NET, I can confirm that this code as an example works properly:
MongoClient client = new MongoClient(); // connect to localhost
MongoServer server = client.GetServer();
MongoDatabase test = server.GetDatabase("test");
MongoCollection examples = test.GetCollection("examples");
string id = "52bc958ca45026c2ff24f90b";
IMongoQuery query = Query.EQ("_id", ObjectId.Parse(id));
UpdateBuilder ub = Update.Set("Name", "George");
WriteConcernResult updatedBook = examples.Update(query, ub);
Using this collection data:
> db.examples.remove()
> db.examples.insert({Name:"Larry"})
> db.examples.find()
{ "_id" : ObjectId("52bc958ca45026c2ff24f90b"), "Name" : "Larry" }
Then, run the C# code above and check the collection again:
> db.examples.find()
{ "Name" : "George", "_id" : ObjectId("52bc958ca45026c2ff24f90b") }
While the WriteConcernResult class itself isn't a BsonDocument, the Response property contains the response from the command.
I also removed the unnecessary Query.And, as it's doesn't do anything when there's only one condition:
query = { "_id" : ObjectId("52bc958ca45026c2ff24f90b") }
ub = { "$set" : { "Name" : "George" } }