Compare the field values in MongoDB - c#

i have two collection A and B
for A contains
{
"_id" : ObjectId("4fb2143af31dfd122ce39c4b"),
"Name" : "Freelander 2.2D",
"Manufacture" : "Landrover"
}
and B ,
{
"_id" : ObjectId("4fb21439f31dfd122ce39c4a")
"Name" : "Rangerover",
"Manufacture" : "Landrover",
}
let me know how to check field values same(here it is "Name" have different values) for A and B in C# driver .If it finds differences i need to update too
Please shed some light on this,Thanks in advance

You can't do queries that involve more than one collection. One query - one collection, period.

Well, Sergio is mostly right (I can't see a way to do this using a language driver), but it is possible using the shell:
var a_in_b = function(o){
var numB = db.B.find({Name:o.Name}).count();
if (numB > 0) print (o.Name + " is in both A and B");
}
> db.A.find()
{ "_id" : ObjectId("4fb2143af31dfd122ce39c4b"), "Name" : "Freelander 2.2D", "Manufacture" : "Landrover" }
> db.B.find()
{ "_id" : ObjectId("4fb667d60569d84fec6ef57e"), "Name" : "Rangerover", "Manufacture" : "Landrover" }
{ "_id" : ObjectId("4fb66a830569d84fec6ef57f"), "Name" : "Freelander 2.2D", "Manufacture" : "Landrover" }
> db.A.find().forEach(a_in_b);
Freelander 2.2D is in both A and B
If your requirement is an admin-related one, this might be what you're looking for. If you're wanting to do this from the C# driver (like a SQL join, I guess), then no, you can't.

Related

Dynamically Query a Mongo Collection in c#

I'm new to C# mongo,earlier worked on Node and Mongo.
i have a collection called tasks.Below is a sample record.
{
"_id" : ObjectId("6193bfba23855443a127466a"),
"taskIdentifier" : LUUID("00000000-0000-0000-0000-000000000000"),
"title" : "PR Liquidators",
"company" : "iuytreugdfh",
"purpose" : "test purpose",
"column" : "Search",
"assignTo" : "Shiva",
"assignToId" : ObjectId("61933b47a79ac615648a7855"),
"assignToImage" : null,
"notes" : "ggh#William james ",
"done" : 0,
"taskID" : "00029",
"status" : "Pending",
"states" : [
"Alabama - AL",
"Alaska - AK"
],
"active" : true,
"updatedAtUtc" : ISODate("2021-11-18T12:26:37.616Z"),
"updatedBy" : ""
}
in my c# webapi Project i always get a array called filterCriteria from api request of below form:
filterCriteria=[
{key:"purpose",value:"test purpose",type:"eq"},
{key:"active",value:true,type:"eq"}
]
Now I want to query the mongo collection tasks using the given filterCriteria.
tried something using LINQ statements but no use --hardcoding works but dynamically not working.
How can I achieve this???
maybe you are looking for Builders:
public enum FilterType{
eq=1,//equal
gt=2//greater than
}
//************
var builder = Builders<FilterCritertiaModel>.Filter;
var query = builder.Empty;
foreach(var filterCriteriaItem in filterCriteria){
switch (filterCriteriaItem.type) {
case eq:
query &= builder.Eq(filterCriteriaItem.Key, filterCriteriaItem.Value);
case gt:
query &=builder.Gt(filterCriteriaItem.Key, filterCriteriaItem.Value);
//all cases....
}

Find if an element in array has value equal to parent element value

Let's say we have a collection of documents like this one:
{
"_id" : ObjectId("591c54faf1c1f419a830b9cf"),
"fingerprint" : "3121733676",
"screewidth" : "1920",
"carts" : [
{
"cartid" : 391796,
"status" : "New",
"cart_created" : ISODate("2017-05-17T13:50:37.388Z"),
"closed" : false,
"items" : [
{
"brandid" : "PIR",
"cai" : "2259700"
}
],
"updatedon" : ISODate("2017-05-17T13:51:24.252Z")
},
{
"cartid" : 422907,
"status" : "New",
"cart_created" : ISODate("2017-10-23T08:57:06.846Z"),
"closed" : false,
"items" : [
{
"brandid" : "PIR",
"cai" : "IrHlNdGtLfBoTlKsJaRySnM195U"
}
],
"updatedon" : ISODate("2017-10-23T09:46:08.579Z")
}
],
"createdon" : ISODate("2016-11-08T10:29:55.120Z"),
"updatedon" : ISODate("2017-10-23T09:46:29.486Z")
}
How do you extract only the documents where no item in the array $.carts have $.carts.closed set to true and $.carts.updatedon greater than $.updatedon minus 3 days ?
I know how to do find all the documents where no item in the array satisfy the condition $and: [closed: {$eq: true}, {updatedon: {$gt : new ISODate("2017-10-20T20:15:31Z")}}]
But how can you reference the parent element $.updatedon for the comparison?
In plain mongodb shell query language it would aleady be of help.
But I am actually accessing it using c# driver, so my query filter is like this:
FilterDefinition<_visitorData> filter;
filter = Builders<_visitorData>.Filter
.Gte(f => f.updatedon, DateTime.Now.AddDays(-15));
filter = filter & (
Builders<_visitorData>.Filter
.Exists(f => f.carts, false)
| !Builders<_visitorData>.Filter.ElemMatch(f =>
f.carts, c => c.closed && c.updatedon > DateTime.Now.AddDays(-15)
)
);
How can I replace DateTime.Now.AddDays(-15) with a reference to the document root element updatedon?
You can project the difference of carts.updatedon and updatedon and then filter out the results from this aggregation pipeline.
coll.aggregate([{'$unwind':'$carts'},
{'$match':{'closed':{'$ne':true}}},
{'$project':{'carts.cartid':1,'carts.status':1,'carts.cart_created':1,'carts.closed':1,'carts.items':1,'carts.updatedon':1,'updatedon':1,'diff':{'$subtract':['$carts.updatedon','$createdon']}}},
{'$match': {'diff': {'$gte': 1000 * 60 * 60 * 24 * days}}}])
days = 3 will filter out results more than 3 days difference documents.
I have just given the example of how you can use $subtract to find date difference and filter documents based on that.
well I was in a similar situation few days back.
I tackled it by using Jobject of Newtonsoft.Json.
Create a function to return bool which actually process each document take it as input.
Jobject jOb=Jobject.parse(<Your document string>);
JArray jAr=JArray.Parse(jOb["carts"]);
If(jOb["updateon"]=<Your Business Validation>)
{
foreach(var item in jAr)
if(item["closed"]==<Your validation>){ return true}
}
return false;
I hope this helps :)
If you handling with any null values in those properties then please use Tryparse and out variable.

C# MongoDB index causes weird duplicate exceptions

we have a problem with our indexes. We have an index on our emails but it throws errors like such:
> db.User.insert({email: "hell33o#gmail.com", "_id" : BinData(3,"iKyq6FvBCdd54TdxxX0JhA==")})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: placetobe.User.$email_text dup key: { : \"com\", : 0.6666666666666666 }"
}
})
when we have the index created with our C# driver like this
Created by C# with:
CreateIndexOptions options = new CreateIndexOptions {Unique = true};
_collection.Indexes.CreateOneAsync(Builders<User>.IndexKeys.Text(_ => _.email), options);
resulted in
{
"v" : 1,
"unique" : true,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "email_text",
"ns" : "placetobe.User",
"weights" : {
"email" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 2
}
but if we create it with the MongoDB console like this it works:
{
"v" : 1,
"unique" : true,
"key" : {
"email" : 1
},
"name" : "email_1",
"ns" : "placetobe.User"
}
I don't understand the difference between the two indexes, but they have an effect on our DB. We also have problems with a Collectin that saves names. we get duplicate exceptions on "Molly" if we try to insert "Molli". With the emails is seems to give us errors whenever we have two "gmail" emails in the collection or two ".com" emails etc.
This is a University project and we have to turn it in tomorrow. we're really in trouble, help would be much appreciated
You don't want your email to be a text Index. Text indices allow you to search large amounts of text in MongoDB like if you were parsing through comments or something. All you want is to make sure your emails aren't duplicated so you should use an ascending or descending index.
CreateIndexOptions options = new CreateIndexOptions {Unique = true};
_collection.Indexes.CreateOneAsync(Builders<User>.IndexKeys.Ascending(_ => _.email), options)

How to find number of distinct fields in a collection in mongodb

As MongoDB provides the flexibility to store the unstructured data,
Is there any way in mongodb C# driver, I can find the number of distinct fields name from a collection.
I mean to say
{
"_id" : ObjectId("52fb69ff1ecf0322f0ab3129"),
"Serial Number" : "1",
"Name" : "Sameer Singh Rathoud",
"Skill" : "C++",
"City" : "Pune",
"Country" : "India"
}
{
"_id" : ObjectId("52fb69ff1ecf0322f0ab312a"),
"Serial Number" : "2",
"Name" : "Prashant Patil",
"DOB" : "31/07/1978",
"Location" : "Hinjewadi",
"State" : "Maharashtra",
"Country" : "India"
}
I want to get [_id, Serial Number, Name, DOB, Skill, City, State, Country]
i also faced this issue. If you till not got proper solution or for new person who searching solution for this kind of question they can use this.
var keys = [];
db.Entity.find().forEach(function(doc){
for (var key in doc){
if(keys.indexOf(key) < 0){
keys.push(key);
}
}
});
print(keys);

MongoDb EnsureIndex looks have a bug

I am battling strange behavior of index creation from hours. I am trying to re-build my sample datas so i drop my collection before insert new datas and before insert new datas i create indexes again like below.
db.GetCollection("Posts").EnsureIndex("Name","Title","Owner");
After that i am trying to Execute sorted Query but MongoDb throws exception and says that
QueryFailure flag was too much data for sort() with no index. add an index or specify a smaller limit
But if i put this line code db.GetCollection("Post").EnsureIndex("Name"); before execute query, it works without problem. Then i have realized that if i use this before rebuild datas it works. There should to be a bug in overloading method or something i have missed.
I am using 10Gen .net driver version 1.2 and i have checked which indexes exist before execure query. Here it is
db.GetCollection("Posts").EnsureIndex("Name","Title","Owner");
db.GetIndexes();//result
[0]: { "v" : 1, "key" : { "_id" : 1 }, "ns" : "Posts", "name" : "_id_" }
[1]: { "v" : 1, "key" : { "Name" : 1, "Title" : 1, "Owner" : 1 }, "ns" : "Posts", "name" : "Name_1_Title_1_Owner_1_" }
db.GetCollection("Posts").EnsureIndex("Title") // i call this for other indexes too
db.GetIndexes();
[0]: { "v" : 1, "key" : { "_id" : 1 }, "ns" : "Posts", "name" : "_id_" }
[1]: { "v" : 1, "key" : { "Name" : 1 }, "ns" : "Posts", "name" : "Name_1" }
[2]: { "v" : 1, "key" : { "Title" : 1 }, "ns" : "Posts", "name" : "Title_1" }
[4]: { "v" : 1, "key" : { "Owner" : 1 }, "ns" : "Posts", "name" : "Owner_1" }
I can't tell from your example exactly what you think isn't working.
One thing to keep in mind is that EnsureIndex only knows what's going on within your own process. So if you remove an index or drop a collection using the mongo shell EnsureIndex won't pick up on that. You can use CreateIndex instead of EnsureIndex if you want to make sure the index exists regardless of what other processes might have done in the meantime.
Let me know if you can provide more details on how to reproduce what you are seeing.

Categories