MongoDb c# driver 2.0 bulk update error - c#

I try to perform bulk update operation using Official Mongo c# 2.0 driver via the following code :
var query =
Builders<Profile>.Filter.In(p => p.userId, listBounce.Values.ToList()) &
Builders<Profile>.Filter.In(p => p.ID, listBounce.Keys.Select(x=> new ObjectId(x)).
ToList());
var update = Builders<Profile>.Update.Set(p => p.MailLists[-1].Status, (int)wrongEmailStatusAssetId);
dbCollection.UpdateManyAsync(query, update).Wait();
But there is the following error has been occurred
{"A write operation resulted in an error.\r\n
The positional operator did not find the match needed from the query.
Unexpanded update: p2l.$.status"}
I need to update each element's property in array which matches the query.
The documents structure is :
{
"_id" : ObjectId("55eeb5da965bb036984110b9"),
"created" : ISODate("2015-09-08T10:17:59.784Z"),
"userId" : 13929,
"email" : "go-get#yandex.ru",
"firstName" : "Skrillex",
"lastName" : "Skrillex",
"phoneNumber" : "",
"isUnsubscribed" : false,
"isAboveLimit" : false,
"status" : 0,
"userAgent" : 9760,
"isDeleted" : false,
"p2l" : [
{
"listId" : 45165,
"status" : 131,
"subscriptionDate" : ISODate("2015-09-04T06:24:55.763Z")
}
]
}

Just add Builders<Profile>.Filter.Exists(p=>p.MailLists) to query and the issue could be solved.

Related

I want to retrieve New_amt field from following document using c#

I want to retrieve New_amt field from following document using C# :
> db.Customer.find().pretty()
{
"_id" : ObjectId("5c6daad5fc5bef1b941bec3c"),
"Customer_Id" : "1",
"Name" : "aaaaa",
"Address" : "lalalal",
"PhoneNo" : "7878787",
"OptionalNo" : "7878787",
"Date" : ISODate("2019-02-20T19:30:29.095Z"),
"Installment" : [
{
"id" : ObjectId("5c6dab0bfc5bef1b941bec3f"),
"New_amt" : "0",
"Net_amt" : "6000",
"Paid" : "200",
"Remains" : "5800",
"Date" : ISODate("2019-02-20T19:31:23.772Z")
}
]
}
you need MongoDriver to c#, one time you have that
instance it
var _client = new MongoClient("mongodb://localhost:27017");
var _database = _client.GetDatabase("YOUR DATABASE");
var _bitCollection = _database.GetCollection<MODEL>("YOUR COLLECTION");
one time you have that you can filter it
var filter = Builders<MODEL>.Filter.Eq(fieldName, fieldValue);
var result = await _bitCollection.Find(filter).ToListAsync();
and result return a List, if don't have model you can use
dynamic as model, but it have some many problems sometimes

Mongodb Update or insert in c#

I want to update or insert into to mongo collection "Member". Under this collection i have an array MagazineSubscription. Here magazine Code is unique. Please refer the sample JSON.
So if need to update or insert into mongo using C# mongo driver.
First I need to check this code exist
2, If it exist update one
If it does not exist insert.
Is there any way I can do in one step. Like if it already exist update otherwise insert. Instead of hit twice. Because my collection is very big.
{
"_id" : ObjectId("5c44f7017en0893524d4e9b1"),
"Code" : "WH01",
"Name" : "Lara",
"LastName" : "John",
"DOB" : "12-10-2017",
"Gender" : "Male",
"Dependents" : [
{
"RelationShip" : "Son",
"Name" : "JOHN",
"DOB" : "01-01-1970",
"Gender" : "Male",
"Address" : "Paris",
"ContactNumber" : "+312233445666"
},
{
"RelationShip" : "Wife",
"Name" : "Marry",
"DOB" : "01-01-1980",
"Gender" : "Female",
"Address" : "Paris",
"ContactNumber" : "+312233445666"
}
]
"Matrimony" : [
{
"Fee" : 1000.0,
"FromDate" : "01-01-2015",
"ToDate" : "01-01-2017",
"Status" : false
}
],
"MagazineSubscription" : [
{
"MagazineCode" : "WSS",
"DateFrom" : "01-05-2018",
"DateTo" : "01-01-2020",
"PaidAmount" : 1000.0,
"ActualCost" : 1500.0,
"Status" : false,
"DeliveryStatus" : [
{
"ReturnedDate" : "10-01-2019",
"Comment" : "Returned because of invalid address"
},
{
"ReturnedDate" : "10-02-2019",
"Comment" : "Returned because of invalid address"
}
]
}
]
}
Use mongodb's update operation with upsert:true.
Please refer here: https://docs.mongodb.com/manual/reference/method/db.collection.update/
Here's a sample from the page:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>, //you need this option
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
And here's a similar question according to what you need:
Upserting in Mongo DB using official C# driver
EDIT 1
Steps:
First you need to write a filter to scan if the document exists. you can check any number of keys (Essentially a document).
Write the update section with the keys you'd like to update (Essentially a document).
Set upsert to true.
Mongodb will use your filter to search the document. If found, it will use the update section to perform the update mentioned by you.
In case the document does not exist, a new document will be created by using the filter keys + keys in the update part.
Hope that makes things clear as I have never used a C# mongo driver. So I won't be able to provide you the exact syntax.
EDIT 2
I'm providing #jeffsaracco's solution here:
MongoCollection collection = db.GetCollection("matches");
var query = new QueryDocument("recordId", recordId); //this is the filter
var update = Update.Set("FirstName", "John").Set("LastName","Doe"); //these are the keys to be updated
matchCollection.Update(query, update, UpdateFlags.Upsert, SafeMode.False);

Nested array $pull query using C# MongoDB driver

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));

Mongodb performance issue with simple search query

This is a sample structure of a collection i am having in mongodb, likewise some 60+ lakh similar records are there in one collection. We moved to mongodb seeing the fast accessing performance,but now its bit hard to say evean simple searching is taking huge time. I have given index for the search params. For name searching (search params MNG_FIRST_NAME, MNG_MIDDLE_NAME, MNG_LAST_NAME, MNG_ALIASIST.AKAFIRST_NAME, MNG_ALIASIST.AKALAST_NAME).
Please consider is the method i'm following the correct way with mongodb.
Please find the code sample and collection structure below i'm using.
{
"_id" : ObjectId("5308e2e1f525bc0f0472cbf6"),
"MNG_UID" : "1389120",
"MNG_CATEGORY" : "OFFICER",
"MNG_FIRST_NAME" : "JOHN",
"MNG_LAST_NAME" : "DOE",
"MNG_MIDDLE_NAME" : "MARK",
"MNG_CREATEDON" : "2010-11-19",
"MNG_UPDATEDON" : "2014-01-01",
"MNG_TITLE" : "Dr",
"MNG_REMARKS" : "",
"MNG_TYPE" : "WORLDCHECK",
"MNG_PROGRAMLIST" : [],
"MNG_IDLIST" : [],
"MNG_ALIASIST" : [
{
"AKAUID" : "101",
"AKATYPE" : "ALIAS",
"AKACATEGORY" : "",
"AKAFIRST_NAME" : "JOHNNY TURA, DOE",
"AKALAST_NAME" : ""
},
{
"AKAUID" : "102",
"AKATYPE" : "ALIAS",
"AKACATEGORY" : "",
"AKAFIRST_NAME" : "MARK TURA, DOE",
"AKALAST_NAME" : ""
}
],
"MNG_ADDRESSLIST" : [
{
"ADDRESSUID" : "",
"ADDRESS1" : "Dakar",
"ADDRESS2" : "Dakar",
"ADDRESS3" : "SENEGAL",
"ADDRESSCITY" : "Dakar",
"ADDRESSCOUNTRY" : "SENEGAL",
"ADDRESSPOCODE" : "",
"ADDRESSSTATE" : "Dakar"
}
],
"MNG_NATIONALITYLIST" : [
{
"NATUID" : "",
"NATCOUNTRY" : "ISRAEL",
"NATMAINENTRY" : ""
},
{
"NATUID" : "",
"NATCOUNTRY" : "AMERICIAN",
"NATMAINENTRY" : ""
}
],
"MNG_CITIZENSHIPLIST" : [],
"MNG_DOBLIST" : [],
"MNG_PLACEOBLIST" : [],
"MNG_ADDINFOLIST" : []
}
code used to obtain collection using mongodb c# driver
string MNG_REMTNAME = "JOHN";
var collection = mongoDB.GetCollection<EMPLOYEES>("EMPLOYEES");
if (!string.IsNullOrEmpty(MNG_REMTNAME))
{
IMongoQuery MFName = new QueryDocument();
MFName = Query.Or(Query.Matches("MNG_FIRST_NAME", MNG_REMTNAME.ToUpper()),
Query.Matches("MNG_MIDDLE_NAME", MNG_REMTNAME.ToUpper()),
Query.Matches("MNG_LAST_NAME", MNG_REMTNAME.ToUpper()),
Query.ElemMatch("MNG_ALIASIST", Query.Or(Query.Matches("AKAFIRST_NAME",
MNG_REMTNAME.ToUpper())))
);
}
var colln = collection.Find(MFName).ToList();
Please help with some solution to increase the performance.
Change the line
Query.ElemMatch("MNG_ALIASIST", Query.Or(Query.Matches("AKAFIRST_NAME",
MNG_REMTNAME.ToUpper())))
for this one
Query.ElemMatch("MNG_ALIASIST", Query.EQ("AKAFIRST_NAME", MNG_REMTNAME.ToUpper()))
Also have in mind that searching in MongoDB Arrays is very expensive unless you have the proper Indexes. So make sure that you have an index with at least the field MNG_ALIASIST.
Consider creating a Multikey index for this field http://docs.mongodb.org/manual/core/index-multikey/

Insert in to a nested array Using C# Official Driver MongoDB

Here is my exact schema:
{
"_id" : ObjectId("4fb4fd04b748611ca8da0d48"),
"Name" : "Categories",
"categories" : [{
"_id" : ObjectId("4fb4fd04b748611ca8da0d46"),
"name" : "Naming_Conventions",
"sub-categories" : [{
"_id" : ObjectId("4fb4fd04b748611ca8da0d47"),
"name" : "Namespace_Naming",
"standards" : []
}]
}]
}
As you can see I have an array named "standards" nested way down in there. How would I programmatically insert in to that using the C# driver? I have tried all of the examples I have found online but none of them are working.
Something like the below. Obviously, if any of these are not present on the way down to it, you're going to get a null reference exception.
var doc = collection.FindOne(Query.EQ("_id", new ObjectId("4fb4fd04b748611ca8da0d48")));
var standards = doc["categories"]
.AsBsonArray[0]
.AsBsonDocument["sub-categories"]
.AsBsonArray;
standards.Add(new BsonDocument());
collection.Save(doc);

Categories

Resources