MongoDB sum values in document - c#

I'm making an application with MongoDB and C#. I use the MongoDB driver.
{
_id: ObjectId("5099803df3f4948bd2f98391"),
Title: "Test",
Rating: {
1234 : 4.0,
4689 : 2.5,
1987 : 1.5
}
}
Now I want to get the average rating. So (4.0+2.5+1.5) / 3.
But how do I do this with MongoDB and the C# driver.
I'm trying to unwind and then count. But it's not working.

You can use $objectToArray (from mongo version 3.4.4) to convert object to array and calculate $avg
db.t71.aggregate([
{$addFields : {data : {$objectToArray : "$Rating"}}},
{$addFields : {avg : {$avg : "$data.v"}}}
]).pretty()
aggregation
> db.t71.aggregate([{$addFields : {data : {$objectToArray : "$Rating"}}}, {$addFields : {avg : {$avg : "$data.v"}}}]).pretty()
{
"_id" : 1,
"Title" : "Test",
"Rating" : {
"1234" : 4,
"1987" : 1.5,
"4689" : 2.5
},
"data" : [
{
"k" : "1234",
"v" : 4
},
{
"k" : "1987",
"v" : 1.5
},
{
"k" : "4689",
"v" : 2.5
}
],
"avg" : 2.6666666666666665
}

Related

Not getting my expectation result in Join Query for multiple conditions using C# mongodb

I am trying to compare the two collections in MongoDB C# for so many times but I am not getting the expectation result.
Here is my code.
UserDetails Collection
{
"_id" : ObjectId("585bc1b137bd32466cfe1472"),
"NTID" : "kram",
"FirstName" : "KRamesh"
}
{
"_id" : ObjectId("585bc1b137bd32466cfe1473"),
"NTID" : "raj",
"FirstName" : "Rajan"
}
ReportDetails Collection
{
"_id" : ObjectId("59d347c77ab9655380bdb452"),
"FaxID" : "123",
"CreatedBy" : "kram",
"CreatedDate" : ISODate("2017-10-03T08:14:18.323Z"),
"LastModifiedBy" : "kram",
"LastModifiedDate" : ISODate("2018-02-01T10:25:14.719Z")
}
{
"_id" : ObjectId("59d347c77ab9655380bdb453"),
"FaxID" : "124",
"CreatedBy" : "raj",
"CreatedDate" : ISODate("2017-10-03T08:14:18.323Z"),
"LastModifiedBy" : "kram",
"LastModifiedDate" : ISODate("2018-02-01T10:25:14.719Z")
}
BsonResult = Collection.Find(finalQuery).OrderByDescending(c => c[_SortBy]).Skip(Skip).Take(Take).ToList();
var details = (from report in BsonResult.AsQueryable()
join user in CollectionUserDetails.AsQueryable()
on report["CreatedBy"] equals user["NTID"]
into joinedreport
select new
{
joinedreportings = joinedreport
}).ToList();
My Expectation Result look like
{
"_id" : ObjectId("59d347c77ab9655380bdb452"),
"FaxID" : "123",
"CreatedBy" : "KRamesh",
"CreatedDate" : ISODate("2017-10-03T08:14:18.323Z"),
"LastModifiedBy" : "KRamesh",
"LastModifiedDate" : ISODate("2018-02-01T10:25:14.719Z")
}
{
"_id" : ObjectId("59d347c77ab9655380bdb453"),
"FaxID" : "124",
"CreatedBy" : "Rajan",
"CreatedDate" : ISODate("2017-10-03T08:14:18.323Z"),
"LastModifiedBy" : "KRamesh",
"LastModifiedDate" : ISODate("2018-02-01T10:25:14.719Z")
}
Please give me the solution..
Thanks,
Pari

Is it possible to know how much time MongoDB has spent for parsing a query?

I have a query which filter a field against a large (> 100K) number of values using the $in operator. It is quite slow. There is an index on the field (IXSCAN is reported by profiler).
I was wondering if there was any way to see how much time MongoDB take to parse
the query (which is sent as BSON if i am not mistaken).
I think C# (since i'm using C# driver) is also taking some time to generate the BSON data but it cannot be reported by MongoDB since it's happening client side.
EDIT: here is the query plan:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "Foo.Bar",
"indexFilterSet" : false,
"parsedQuery" : {
"ExternalKeys" : {
"$in" : [
{
"A" : 0,
"B" : 0,
"C" : 34228
},
{
"A" : 0,
"B" : 1,
"C" : 540830
},
... (many like that)
{
"A" : 5,
"B" : 3,
"C" : 773660
}
]
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"ExternalKeys" : 1
},
"indexName" : "ExternalKeys_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"ExternalKeys" : [
"ExternalKeys"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"ExternalKeys" : [
"[{ A: 0.0, B: 0.0, C: 34228.0 }, { A: 0.0, B: 0.0, C: 34228.0 }]",
"[{ A: 0.0, B: 1.0, C: 540830.0 }, { A: 0.0, B: 1.0, C: 540830.0 }]",
... (many like that)
"[{ A: 5.0, B: 3.0, C: 773660.0 }, { A: 5.0, B: 3.0, C: 773660.0 }]"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "....",
"port" : 27017,
"version" : "3.4.10",
"gitVersion" : "078f28920cb24de0dd479b5ea6c66c644f6326e9"
},
"ok" : 1
}

C# mongodb insert inside a document in a collection

Following is the structure of doc.
{
"name" : "Apparel & Accessories",
"description" : "Apparel & Accessories",
"logoPath" : "apparel_n_accessories.png",
"categoryCode" : "APP-N-ACC",
"isActive" : 1,
"subCategory" : [
{
"name" : "Clothing",
"description" : "Clothing",
"logoPath" : "clothing.png",
"categoryCode" : "CLOTH",
"isActive" : 1,
"subCategory" : [
{
"name" : "Outerwear",
"description" : "Outerwear",
"logoPath" : "outerwear.png",
"categoryCode" : "OUTWER",
"isActive" : 1,
"subCategory" : [
{
"name" : "Coats & Jackets",
"description" : "Coats & Jackets",
"logoPath" : "coats_n_jackets.png",
"categoryCode" : "COT-N-JACT",
"isActive" : 1,
"subCategory" : [ ]
}
]
},
{
"name" : "Jewelry",
"description" : "Jewelry",
"logoPath" : "jewelry.png",
"categoryCode" : "JEWL",
"subCategory" : [
{
"name" : "Rings",
"description" : "Rings",
"logoPath" : "rings.png",
"categoryCode" : "RINGS",
"isActive" : 1,
"subCategory" : [ ]
}
]
}
]
}
]
}
I want to insert into subcategory of "Apparel & Accessories" with following content :
{
"name" : "XYZ",
"description" : "XYZ",
"logoPath" : "XYZ.png",
"categoryCode" : "XYZ",
"isActive" : 1,
"subCategory" : [ ]
}
We are using c# ver 1.8 legacy drivers to connect mongodb.
Can anyone please suggest how to find any level object and add in it.
Do something like this:
var filter = Builders<Category>
.Filter.Eq(c => c.name, "Apparel & Accessories");
var update = Builders<Category>.Update
.Push<Category>(c => c.subCategory, mySubCategory);
await collection.FindOneAndUpdateAsync(filter, update);

mongoDB insert item in Array

{
"_id" : ObjectId("5431f38c4ba4dd20408b0432"),
"UserID" : "1",
"Status" : {
}
},
"ListFilterType" : 1,
"IssueCategories" : [
{
"_id" : ObjectId("000000000000000000000000"),
"IssueCategoryID" : 2,
"IssueCagetoryName" : "test",
"MatchKeyword" : "test",
"MatchKeywordID" : 2
}
]
}
edit :
my expactation is like this.
{
"_id" : ObjectId("5431f38c4ba4dd20408b0432"),
"UserID" : "1",
"Status" : {
}
},
"ListFilterType" : 1,
"IssueCategories" : [
{
"_id" : ObjectId("000000000000000000000000"),
"IssueCategoryID" : 2,
"IssueCagetoryName" : "test",
"MatchKeyword" : "test",
"MatchKeywordID" : 2
},
{
"_id" : ObjectId("000000000000000000000001"),
"IssueCategoryID" : 3,
"IssueCagetoryName" : "test2",
"MatchKeyword" : "test2",
"MatchKeywordID" : 3
},
{
"_id" : ObjectId("000000000000000000000004"),
"IssueCategoryID" : 4,
"IssueCagetoryName" : "test4",
"MatchKeyword" : "test34",
"MatchKeywordID" : 4
}
]
i have a type list as "IssueCategories". You can see my mongodb structure above. If root _id = my parameter, I want to add to mongodb.
I hope I explained right
thanks
You should use either $push or $addToSet to update document.
$push will add all element in IssueCategories including duplicates also.
While in $addToSet do not insert duplicate elements(object) in array if whole object is present in array.
Using $push:
db.collection.update({
"_id": ObjectId("5431f38c4ba4dd20408b0432") // you can add any other param
}, {
$push: {
SCSIssueCategories: {
"_id": ObjectId("11111111111111111"), //ur id here
"IssueCategoryID": 3,
"IssueCagetoryName": "Sözleşme1",
"MatchKeyword": "abonelik süresi1",
"MatchKeywordID": 3
}
}
})
Here is query using $addToSet:
db.collection.update({
"_id": ObjectId("5431f38c4ba4dd20408b0432")
}, {
$addToSet: {
SCSIssueCategories: {
"_id": ObjectId("11111111111111111"), //ur id here
"IssueCategoryID": 3,
"IssueCagetoryName": "Sözleşme1",
"MatchKeyword": "abonelik süresi1",
"MatchKeywordID": 3
}
}
})
**If single param have different value then it will be inserted in array using $addToSet. **

MongoDb Query Array on C#

Im dba and development a C# Web App to get information from Mongodb, but when i try to get information from an array attribute, the C# show me all element of the document that contain the element that i find. I just want to get the specific element, not all.
I have this document:
{
"_id" : ObjectId("53b1b7dcb830980744687bd4"),
"i_nombre" : "Centro Comercial",
"i_direccion" : {
"i_d_pais" : "Panamá",
"i_d_ciudad" : "Panamá",
"i_d_provincia" : "Panamá",
"i_d_distrito" : "Chilibre",
"i_d_corregimiento" : "Alcalde Diaz",
"i_d_calle" : "Primera"
},
"i_correo_e" : "imqv#imqv.com.pa",
"i_telefono" : {
"i_t_iglesia" : "268-5000",
"i_t_colegio" : "268-5001",
"i_t_radio" : "268-5002"
},
"i_estado" : 1,
"i_sector" : [
{
"_id" : ObjectId("53b6d903b8309826e891eefe"),
"i_s_color" : "Amarillo",
"i_s_localizacion" : {
"i_s_l_provincia" : "Panamá",
"i_s_l_distrito" : "Chilibre",
"i_s_l_corregimiento" : "San Miguelito"
},
"i_s_supervisor" : []
},
{
"_id" : ObjectId("53b6d903b8309826e89100f0"),
"i_s_color" : "Rojo",
"i_s_localizacion" : {
"i_s_l_provincia" : "Panamá",
"i_s_l_distrito" : "Arraijan",
"i_s_l_corregimiento" : "Burunga"
},
"i_s_supervisor" : []
},
{
"_id" : ObjectId("53b6d903b8309826e89220f0"),
"i_s_color" : "Azul",
"i_s_localizacion" : {
"i_s_l_provincia" : "Panamá",
"i_s_l_distrito" : "Colon",
"i_s_l_corregimiento" : "Chilibre"
},
"i_s_supervisor" : []
}
]
};
When i execute this query on mongodb
db.iglesia.find
(
{ "_id" : ObjectId("53b1b7dcb830980744687bd4") }
, {
i_sector: {
$elemMatch: { "_id" : ObjectId("53b6d903b8309826e891eefe") }
}
}
);
i get:
{
"_id" : ObjectId("53b1b7dcb830980744687bd4"),
"i_sector" : [
{
"_id" : ObjectId("53b6d903b8309826e891eefe"),
"i_s_color" : "Amarillo",
"i_s_localizacion" : {
"i_s_l_provincia" : "Panamá",
"i_s_l_distrito" : "Chilibre",
"i_s_l_corregimiento" : "San Miguelito"
},
"i_s_supervisor" : []
}
]
}
Question: How i can get the same result with C#? Just with the $elemMatch that i set on Query.
The reason is that your Mongo shell query is not a find with 2 filters, by church id and sector, it is actually a find by church id and a projection by sector id. You have arranged the braces funny, that's all.
This has 2 filters and no projection:
db.iglesia.find ({"_id": "53b1b7dcb830980744687bd4", i_sector: { $elemMatch: {"_id" : "53b6d903b8309826e891eefe"}}}).pretty()
This has a filter and projection:
db.iglesia.find ({"_id": "53b1b7dcb830980744687bd4"}, {i_sector: { $elemMatch: { "_id": "53b6d903b8309826e891eefe"}}}).pretty()
A complete C# example, for these 2 cases using a newer driver, version 2.3, here on rextester.

Categories

Resources