Query MongoDb from C# - using Linq .Any() with predicate - c#

I have a collection I am trying to query using the c# driver. the document structure is:
{
"_id" : 3121 ,
"Active" : true ,
"CategoryId" : 1 ,
"Crci" : "IH" ,
"CultureId" : null ,
"DateUpdated" : {
"$date" : 1381916923120
} ,
"Description" : "National Careers Service: Actuary" ,
"Keywords" : "" ,
"MaxLevel" : null ,
"MinLevel" : null ,
"PhoneNumber" : " " ,
"Priority" : 1 ,
"Title" : "National Careers Service: Actuary" ,
"WebUrl" : "https://nationalcareersservice.direct.gov.uk/advice/planning/jobprofiles/Pages/actuary.aspx" ,
"CareerCultureExternalResources" : [
{
"CareerId" : 5 ,
"CultureId" : 1 ,
"DisplayOrder" : 1 ,
"ExternalResourceId" : 3121 ,
"Vgs" : null
}
] ,
"SubjectExternalResources" : [ ] ,
"LifestyleCategories" : null
}
the query I am trying to run is:
collection.AsQueryble().Where(
er =>
er.CareerCultureExternalResources.Any(
ccer => ccer.CareerId == request.CareerId && ccer.CultureId == request.CultureId));
passing the values careerId = 637 and cultureId = 1, I get the error: "Unsupported where clause: ((Int32)ccer.CareerId == 637)"
However on the MongoDb tutorials page it says this kind of query is covered:
http://docs.mongodb.org/ecosystem/tutorial/use-linq-queries-with-csharp-driver/
I am using version 1.8.3 of the driver

Currently, using where and a conditional clause like you've done, when using Linq, is limited to a subset of .NET data types. Instead of using a short, use a Int32/(int) instead.

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

How to query from Firebase in c#?

I use firebase.database to make query from Firebase in c#, i want to make like Where in linq But i didn't find any extension method that would help.
I have CallHistory table has many properties like Rate,Id,Status and
make index in Rate property this is json of callhistory
"CallHistory" : {
"0798af9c-180c-4d67-a58d-a47043f7e36f" : {
"CreatedDate" : "0001-01-01T00:00:00Z",
"Id" : "0798af9c-180c-4d67-a58d-a47043f7e36f",
"IsActive" : false,
"IsDeleted" : false,
"Latitude" : 1.5,
"ModifiedDate" : "0001-01-01T00:00:00Z",
"Rate" : 5,
"RecipientId" : "00000000-0000-0000-0000-000000000000",
"Status" : 2,
"StatusDateTime" : "0001-01-01T00:00:00Z",
"longitude" : 1.2
},
"151c7072-0b17-44aa-a834-99c265ef897f" : {
"CreatedDate" : "0001-01-01T00:00:00Z",
"Id" : "151c7072-0b17-44aa-a834-99c265ef897f",
"IsActive" : false,
"IsDeleted" : false,
"Latitude" : 1.5,
"ModifiedDate" : "0001-01-01T00:00:00Z",
"Rate" : 4,
"RecipientId" : "00000000-0000-0000-0000-000000000000",
"Status" : 1,
"StatusDateTime" : "0001-01-01T00:00:00Z",
"longitude" : 1.2
}
}
and write this code
using Firebase.Database;
using Firebase.Database.Query;
var firebase = new FirebaseClient("https://sound-project-42ead.firebaseio.com/");
var calls = await firebase
.Child("CallHistory").OrderBy("Rate").EqualTo("4")
.OnceAsync<CallHistory>();
But it doesn;t return any data.
With search i found that there are function called OrderByChild() , But i did'nt find this method anymore
in firebase.database.query.
Is There any other dll can i install it to find orderbychild().
Firebase Realtime Database queries compare the actual type of the stored data and of the value you specify. And the string "4" is not the same as a numerical value 4.
So you'll want to pass a number:
var firebase = new FirebaseClient("https://sound-project-42ead.firebaseio.com/");
var calls = await firebase
.Child("CallHistory").OrderBy("Rate").EqualTo(4)
...

Store an integer value into ElasticSearch when using Log4Net

I'm logging user actions in ElasticSearch and I'm using C# Log4Net
I'm using the C# NEST library to access the ElasticSearch database.
My log line looks like this:
{
"_index" : "log-2016.07.27",
"_type" : "logEvent",
"_id" : "AVYrwmW5Hc5CAgECpn_X",
"_score" : 1.0,
"_source" : {
"timeStamp" : "2016-07-27T09:49:35.3774113Z",
"message" : "Upload file operation took 11683 ms",
"loggerName" : "Reviewer.Web.WebApi.GroupsController",
"identity" : "",
"level" : "INFO",
"properties" : {
"log4net:UserName" : "CORP\\g",
"log4net:ElapsedTime" : "11683",
"log4net:Identity" : "",
"IP" : "::1",
"log4net:HostName" : "GBWOTIOM68052D",
"#timestamp" : "2016-07-27T09:49:35.3774113Z"
}
}
I'd like to have the log4net:ElapsedTime value stored as an integer instead of a string.
currently I'm doing this when storing an elapsed time:
long ms = 1000;
LogicalThreadContext.Properties["log4net:ElapsedTime"] = ms;
I know I should specify a template in order to tell ElasticSearch to store the elapsed value as an integer but how to do it?
If you want elasticsearch to recognize your field you should send your data value without double-quotes.
curl -XPUT 'localhost:9200/tmp/tmp/1' -d '{
"field1":"3",
"field2":3
}'
-
curl -XGET 'localhost:9200/tmp'
{"tmp":{"aliases":{},"mappings":{"tmp":{"properties":{"field1":{"type":"string"},"field2":{"type":"long"}}}},"settings":{"index":{"creation_date":"1469621916488","uuid":"Qj64-CU5RUW6ShOyRqLZXQ","number_of_replicas":"0","number_of_shards":"1","version":{"created":"1070599"}}},"warmers":{}}}
You can see field1 is string but field2 is numeric.

Compare the field values in MongoDB

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.

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