MongoDb Query Array on C# - 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.

Related

MongoWriteException: A write operation resulted in an error. The positional operator did not find the match needed from the query

I have a collection Zonedetails shown below. below.
I am using C# to Insert or Update a Unit to Units array. If it is an insert I can insert Area blank. If it is an update It should only update the UnitName.
{
"Code" : "Zone1",
"Name" : "ZoneName1",
"Units" : [
{
"UnitCode" : "Unitcode1",
"UnitName" : "UnitCodeName",
"Areas" : [
{
"AreaCode" : "AreaCode1",
"AreaName" : "AreaName1"
}
]
}
]
}
{
"Code" : "Zone2",
"Name" : "ZoneName2",
"Units" : [
{
"UnitCode" : "UnitCode2",
"UnitName" : "UnityName2",
"Areas" : [
{
"AreaCode" : "Areacode2",
"AreaName" : "AreaName2"
}
]
}
]
}
{
"Code" : "Zone3",
"Name" : "ZoneName3",
"Units" : [
{
"UnitCode" : "UnitCode3",
"UnitName" : "UnitName3",
"Areas" : [
{
"AreaCode" : "Areadcode3",
"AreaName" : "AreaName3"
},
{
"AreaCode" : "AreaCode4",
"AreaName" : "Areaname4"
},
{
"AreaCode" : "AreaCode5",
"AreaName" : "Areaname5"
}
]
},
{
"UnitCode" : "UnitCode6",
"UnitName" : "UnitName6",
"Areas" : [
{
"AreaCode" : "AreaCode10",
"AreaName" : "AreaName10"
},
{
"AreaCode" : "AreaCOde11",
"AreaName" : "AreaName10"
},
{
"AreaCode" : "AreaCode12",
"AreaName" : "AreaName12"
}
]
}
]
}
I have writtent a C# code shown below. But getting "The positional operator did not find the match needed from the query"error if the Unit Code does not exist. Added not before unitCode check.
var mongoCollection = _context.GetCollection<Zone>("ZoneDetail");
var filter = Builders<Zone>.Filter.Where(x => x.Code == zoneCode && !x.Units.Any(u => u.UnitCode == unit.UnitCode));
var updateUnitCode = Builders<Zone>.Update.Set(x => x.Units.ElementAt(-1).UnitCode, unit.UnitCode);
var updateUnitName = Builders<Zone>.Update.Set(x => x.Units.ElementAt(-1).UnitName, unit.UnitName);
var result = await mongoCollection.UpdateOneAsync(filter, Builders<Zone>.Update.Combine(updateUnitCode, updateUnitName), new UpdateOptions { IsUpsert = true});
Your error message suggest that filter is not able to find matching element.
Either try to change your input or change your filter criteria.

MongoDB sum values in document

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
}

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

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. **

Why does my Update to a sub document remove the array nature of sub document

I have this
{
"ClockID" : "fd51b6e0-5b81-49ab-8424-71fd768281b2",
"ClockName" : "AAA-TEST123-002",
"FilesList" : [{
"FileName" : "AAA-TEST123-002.mpg",
"FileLocationHistory" : [{
"FullPath" : "192.168.32.166/Ingestion",
"AllowDeleteOnCancel" : false,
"_id" : "565b7343-9dc5-4916-a788-0f392fce2502"
}],
"_id" : "15b54499-a0be-4278-82ed-58c82c13bd40",
}],
"_id" : ObjectId("510164d0a63cfa2250fd6d19"),
"_t" : "ClockRecord"
When I update the FileLocationHistory array document with this:
public void UpdateClockFilesLocationRecord(string collectionName, ClockFileLocationHistoryRecord clockFileLocationHistory, BsonObjectId clockDocumentID, string clockFileDocumentID)
{
var mongoCollection = MongoDatabase.GetCollection<ClockRecord>("Clocks");
var update = Update.Set("FilesList.$.FileLocationHistory", BsonDocumentWrapper.Create<ClockFileLocationHistoryRecord>(clockFileLocationHistory));
var modeResult = mongoCollection.Update(
Query.And(
Query.EQ("_id", clockDocumentID),
Query.EQ("FilesList._id", clockFileDocumentID)
),
update, UpdateFlags.Upsert
);
}
the update goes through but the document is no longer an array:
{
"ClockID" : "fd51b6e0-5b81-49ab-8424-71fd768281b2",
"ClockName" : "AAA-TEST123-002",
"FilesList" : [{
"FileName" : "AAA-TEST123-002.mpg",
"FileLocationHistory" : {
"FullPath" : "192.168.32.166/Ingestion",
"AllowDeleteOnCancel" : false,
"_id" : "565b7343-9dc5-4916-a788-0f392fce2502"
},
"_id" : "15b54499-a0be-4278-82ed-58c82c13bd40",
}],
"_id" : ObjectId("510164d0a63cfa2250fd6d19"),
"_t" : "ClockRecord"
Which means the document tries to de-serialise as an object that the driver does not recognise.
What is wrong with my update code?
Instead of:
var update = Update.Set("FilesList.$.FileLocationHistory", BsonDocumentWrapper.Create<ClockFileLocationHistoryRecord>(clockFileLocationHistory));
You could use push:
var update = MongoUpdate.Push("FilesList.$.FileLocationHistory", BsonDocumentWrapper.Create<ClockFileLocationHistoryRecord>(clockFileLocationHistory));
... to add to the array

Categories

Resources