I'm trying to find the way to make this work.
Documentation of the MongoDbDriver is pretty poor, and just a couple of "solutions" found by google.
I need to remove the field from the database through C# migration script.
var filter = Builders<Person>.Filter.Eq(person => person.Id, personId);
var update = Builders<Person>.Update.Unset(person => person.Address.PostalCode);
collection.UpdateOne(filter, update);
This is what I found as a solution on the net, but this doesn't work. Field is still in the database.
What am I missing?
Just checked, your above query works as expected, see results below before and after:
before updating:
MongoDB Enterprise replset:PRIMARY> db.p.find({})
{ "_id" : ObjectId("616ace670b6d6703634faf70"), "Address" : { "PostalCode" : "200" } }
{ "_id" : ObjectId("616ace660b6d6703634faf6f"), "Address" : { "PostalCode" : "100" } }
after updating by personId = ObjectId("616ace660b6d6703634faf6f")
MongoDB Enterprise replset:PRIMARY> db.p.find({})
{ "_id" : ObjectId("616ace670b6d6703634faf70"), "Address" : { "PostalCode" : "200" } }
{ "_id" : ObjectId("616ace660b6d6703634faf6f"), "Address" : { } }
Related
I have read other posts similar to this one, but since I am new to mongodb and the depth of the subdocument that I have is more then already addressed, I have to ask this question here. My document is as follows:
{
"_id" : "57bae0ad7bbba417fcaec4ca",
"spUserProfile" : null,
"spLinkedBusinesses" : [
{
"_id" : "57bae0ad7bbba417fcaec4c9",
"businessDocuments" : [
{
"_id" : "57bae0fb7bbba417fcaec4cc",
"documentPath" : "/docs/doc1.pdf",
"documentName" : "Doc Hey",
"documentType" : "DPF",
"documentUploadDateTime" : ISODate("2016-08-22T11:24:43.061Z")
},
{
"_id" : "57bae0fd7bbba417fcaec4cd",
"documentPath" : "/docs/doc_mute.pdf",
"documentName" : "Agreements IMP",
"documentType" : "PDF",
"documentUploadDateTime" : ISODate("2016-08-22T11:24:45.229Z")
},
{
"_id" : "57bae0ff7bbba417fcaec4ce",
"documentPath" : "/docs/accounts1.xls",
"documentName" : "Expenses 1",
"documentType" : "XLS",
"documentUploadDateTime" : ISODate("2016-08-22T11:24:47.066Z")
}
]
}
]
}
I have to delete the businessDocuments with id "57bae0fd7bbba417fcaec4cd" (using c# mongodb driver code), the collection is called RefUsers.
PS: I cant use the legacy C# mongodb drivers, so no use of the Query class.
thanks.
Have a look into $pull to remove documents from an embedded array
Pull MongoDB documentation
ElemMatch will also be useful to you here if you are wanting to identify items within embedded arrays
ElemMatch MongoDB documentation
How to do aggregation query with Linq. I know there is a AsQueryable() interface. But it seems throwing errors when I do aggregations.
If I have a collection called person stores data like this:
{
"Name": "Punny",
"Interests": [
1,
2
]
}
and another collection called interests stores data like this:
{
"_id":1,
"name":"music"
},
{
"_id":2,
"name":"read"
}
I want to get something like this:
{
"Name": "Punny",
"Interests": [
"music",
"read"
]
}
How can I achieve this via Linq to with AsQueryable?
I tried this:
_context.People.AsQueryable()
.Select(p => new
{
Name = p.Name,
Interests = p.InterestingIds
.Join(_context.Interests.AsQueryable(),
per => per,
i => i.Id,
(per, i) => new {i.Name})
}).ToList();
It throws a System.NotSupportedException
System.NotSupportedException : Join of type System.Linq.Enumerable is not supported in the expression tree {document}{InterestingIds}.Join([FunnyMongoBlog.interest], per => per, i => i.Id, (per, i) => new <>f__AnonymousType1`1(Name = i.Name)).
I tried my self with a two trip to database:
var person = _context.People.AsQueryable()
.Single(p => p.Name == "Punny");
var ids = person.InterestingIds;
var query = _context.Interests.AsQueryable()
.Where(i => ids.Contains(i.Id)).ToList();
var result = new
{
person.Name,
Interest = query
};
This is working but I wonder if we can do it with one trip so that the database could handle the aggregation.
you can do it in aggregation framework, but I'd to suggest using power of subDocumnets in mongoDB and embed those elements fully in main document. In other words we need to switch from relational thinking to document thinking.
My suggested object shape:
{
"Name" : "Punny",
"Interests" : [{
"_id" : 1,
"name" : "music"
}, {
"_id" : 2,
"name" : "read"
}
]
}
in c# code
class MyClass {
public string Name;
public List < Interest > Interests;
}
class Interest {
public int Id;
public string Name;
}
Now please find bson document needed for that transformation requested in question:
db.col.aggregate([{
$unwind : "$Interests"
}, {
$lookup : {
from : "interests",
localField : "Interests",
foreignField : "_id",
as : "interest"
}
}, {
// now we need to reshape document
$project : {
_id : 1,
Name : 1,
Interests : "$interest.name"
}
},
//group documents back
{
$group : {
_id : {
id : "$_id",
name : "$Name"
},
Interests : {
$push : "$Interests"
}
}
}, {
//final reshape
_id : "$_id.id",
Name : "$_id.name",
Interests : 1
}
])
and decide if embeding is worth a try :-)
Any comments welcome!
I have a collection as "UserRecords". structure for this is as follows
{
"_id" : "ee654ce6-e50d-4243-8738-35c087a85e67",
"_t" : "Animals",
"ClickedOn" : NumberLong(1452600122),
"Category" : "Nature",
"UserId" : "a1",
}
{
"_id" : "ee654ce6-e50d-4243-8738-35c087a85e67",
"_t" : "Abstract",
"ClickedOn" : NumberLong(1247634566),
"Category" : "Modern",
"UserId" : "a1",
}
{
"_id" : "ee654ce6-e50d-4243-8738-35c087a85e67",
"_t" : "Abstract",
"ClickedOn" : NumberLong(1247634440),
"Category" : "Modern",
"UserId" : "a1",
}
and more...
now I want to get Max clicked on for each category. Using latest Mongo C# driver
something like
select Max(clicked) from table group by Category in SQL.
Queries like this can be efficiently processed with the MongoDB Aggregation Framework. However, the queries are written as JSON, making them a bit hard to read.
var dataCollection = Database.GetCollection("UserRecords");
var AggArgs = new AggregateArgs {
Pipeline =
new[] {BsonDocument.Parse(#"{$group : {_id : '$Category', ClickedOn : {$max : '$ClickedOn'}}}")}
};
foreach (var result in dataCollection.Aggregate(AggArgs))
{
Console.WriteLine($"Category: {result["_id"]} Clicked: {result["ClickedOn"]}");
}
From an API I receive a JSON-object that looks like this:
{
"wind" : {
"speed" : 7.31,
"deg" : 187.002
},
"rain" : {
"3h" : 0
},
"clouds" : {
"all" : 92
},
"coord" : {
"lon" : 139,
"lat" : 35
},
"dt" : 1369824698,
"id" : 1851632,
"cod" : 200,
"weather" : [
{
"id" : 804,
"main" : "clouds",
"icon" : "04n",
"description" : "overcast clouds"
}
],
"main" : {
"humidity" : 89,
"temp_max" : 292.04,
"temp_min" : 287.04,
"temp" : 289.5,
"pressure" : 1013
},
"sys" : {
"country" : "JP",
"sunrise" : 1369769524,
"sunset" : 1369821049
},
"name" : "Shuzenji"
}
I would like to assign two of these values to my class:
public class Weather {
public string Name { get; set; }
public string Temp { get; set; }
}
The name I can assign like this:
weather.Name = TheJSON.name.ToString();
But the temp is trickier, because it's nested inside the "main"-array. I´ve seen many examples on how to do this in Javascript but not so much in C#. Thanks!
Main is not an array. It is an object, so
TheJSON.main.temp.ToString()
The easiest way to work with JSON data is to deserialize them as C# objects and directly use them in your application. You can use a tool like JSON C# Class Generator to automatically generate the C# class from the JSON data. Once you have your C# classes generated, you can deserialize the JSON string using the JsonConvert.DeserializeObject(jsonText); The generated code requires Newtonsoft Json.NET which you can easily add as a NuGet package.
If you save your JSON content in D:\test.json, you can use the following code to access the values using the C# objects generated. The example below is to just give you an idea on the usage.
var json = File.ReadAllText(#"D:\test.json");
var weather = JsonConvert.DeserializeObject<Weather>(json);
Console.WriteLine(weather.Name);
Console.WriteLine(weather.Sys.Country);
I Have a mongoDB that contains data in unknown structure, and I want to find all the documents that has a specific BsonElement. Can I do it without the knowledge about the documents structure?
For example, if the documents look like this (and I don't know that) can I find all the documents that has "DBType":"MSSQL"?
There is somting like collection.deepFind(QueryDocument);?
{
"_id" : ObjectId("528fe1602feaa3231c784d92"),
"CurrentJobs" : {
"_t" : "sqQueryJob",
"IsDone" : false,
"ExecuteTime" : ISODate("2013-11-22T22:57:35.733Z"),
"Result" : { },
"DB" : {
"DBType" : "MSSQL",
"Name" : "Data",
"Host" : ".",
"ServiceName" : "DataBase",
"Port" : "1521",
},
"QueryResult" : null,
"Query" : "."
}
}
Thanks!