how to search on mongodb by using runcommand - c#

This is my code... but runcommand doesn't get any results
Notice : "title" is an indexed field
var mongoClient = new MongoClient(ConfigurationManager.AppSettings["connectionString"]);
var server = mongoClient.GetServer();
mongodatabase = server.GetDatabase("Htmlattachment2");
MongoCollection<Department> attachments = mongodatabase.GetCollection<Department>("attachment2");
attachments.EnsureIndex(new IndexKeysBuilder().Ascending("title"));
attachments.Insert(new BsonDocument("title", "The quick brown fox"));
var t = attachments.GetIndexes().ToList();
//foreach (Attachements emp in attachments.FindAll())
//{ }
var textSearchCommand = new CommandDocument
{
{ "text","title" },
{ "search", textBox1.Text }
};
var commandResult = mongodatabase.RunCommand(textSearchCommand);
var response = commandResult.Response["results"].AsBsonArray;
foreach (BsonDocument result in response)
{
// process result
}

It might be easier if you just used LINQ to perform queries. There is a tutorial on how use LINQ with MongoDB here. Note that the MongoDB C# driver translates the LINQ queries to run on the database as native Mongo queries.

Related

Querying product/pricing information against Dynamics 365 tenant using the C# SDK

I am trying to query product related information in a Dynamics 365 tenant (Version 9.2.22101.170) and with Version 9.0.2.46 of the Microsoft.CrmSdk. Mostly I am interested in querying products by the product number to retrieve price information, but later on, I would introduce more parameters. The below is one of the many methods I've tried (I am aware I am projecting only the name for the time being, eventually I would require price information etc):
var cols = new ColumnSet(new String[] { "name" });
QueryByAttribute query = new QueryByAttribute("product");
query.ColumnSet = cols;
query.Attributes.AddRange("productnumber");
query.Values.AddRange("100002");
var results = service.RetrieveMultiple(query);
if (results != null)
{
var entities = results.Entities.ToList();
if (entities != null)
{
var productEnt = (Product)entities.FirstOrDefault();
Console.WriteLine(productEnt.Name);
}
}
This is the error message returned, on the RetrieveMultiple call:
The entity with a name = 'product' with namemapping = 'Logical' was not found in the MetadataCache. MetadataCacheDetails: ProviderType=Dynamic, StandardCache=True, IsLoadedInStagedContext = False, Timestamp=8343791, MinActiveRowVersion=8343791
The same message is returned when calling any other method. It's clear that the issue is not the query, or the columns being returned but the "product".
Sure enough, I am using the below method to get the list of entity names, and the word "Product" does not show up. I think this explains the error message.
public static EntityMetadata[] GetEntities(IOrganizationService organizationService)
{
Dictionary<string, string> attributesData = new Dictionary<string, string>();
RetrieveAllEntitiesRequest metaDataRequest = new RetrieveAllEntitiesRequest();
RetrieveAllEntitiesResponse metaDataResponse = new RetrieveAllEntitiesResponse();
metaDataRequest.EntityFilters = EntityFilters.Entity;
// Execute the request.
metaDataResponse = (RetrieveAllEntitiesResponse)organizationService.Execute(metaDataRequest);
var entities = metaDataResponse.EntityMetadata;
return entities;
}
Is this a permission issue? Do I need to do some extra loading prior to the query? How do you query product/pricing related information in a Dynamics 365 tenant?
I tried searching for related information online, but I was surprised to practically find almost nothing related to Products.
you are using QueryByAttribute rather you should be using QueryExpression
Try below query and it should help.
// Define Condition Values
var query_productnumber = "100002";
// Instantiate QueryExpression query
var query = new QueryExpression("product");
query.Distinct = true;
// Add columns to query.ColumnSet
query.ColumnSet.AddColumns("productid", "name");
// Define filter query.Criteria
query.Criteria.AddCondition("productnumber", ConditionOperator.Equal, query_productnumber);
var results = service.RetrieveMultiple(query);
if (results != null)
{
var entities = results.Entities.ToList();
if (entities != null)
{
var productEnt = (Product)entities.FirstOrDefault();
Console.WriteLine(productEnt.Name);
}
}

How to find a document with Bson type in mongo in c#

I want to find a role details with specified username in MongoDb with Drivers in C#.
I don't want to use any builders or linq methods.
I tried this to insert a Bson document and it worked.
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("test");
var collec = database.GetCollection<BsonDocument>("user");
var documnt = new BsonDocument{
{"username", txtUsername.Text},
{"password", txtPassword.Password}
};
var check_count = collec.CountDocuments(documnt);
But when I tried this code to find a role with username its not working:
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("test");
var collec = database.GetCollection<BsonDocument>("user");
var documnt = new BsonDocument{
{"username", "admin"},
{"role", 1}
};
var role = collec.Find(documnt);
txtTestRole.Text = role.ToString();
I got this as output:
enter image description here
You have to materialize the query.
As you query for single record, you can use IAsyncCursorSourceExtensions.SingleOrDefault Method.
Or you can refer to IFindFluent (Extension methods section) to select the method that is best suited to you.
Next, from returned BsonDocument to select the specific field for the displayed value.
var user = collec.Find(documnt)
.SingleOrDefault();
if (user == null)
{
// Handle user not exist
return;
}
txtTestRole.Text = user["role"].ToString();

How do I query a SQL Server database with a list of parameters in Dapper?

I have a list of objects with various properties. I want to query a database using these properties and get a result list back.
This is what I've tried:
public async Task<IEnumerable<Animal>> GetAnimalsFromAttributesAsync(IEnumerable<AnimalInfo> attributeSets)
{
using (var myDB = new SqlConnection(connectionString))
{
await myDB.OpenAsync();
var results = new List<Animal>();
foreach (var attributeSet in attributeSets)
{
var sql = #"select AnimalID, AnimalTypeID, AnimalColor
from Animals
where AnimalTypeID = #AnimalTypeID
and AnimalColorID = #AnimalColorID";
var result = myDB.Query<Animal>(sql, attributeSet);
results.AddRange(result);
}
return results
}
}
This works ok for small numbers of properties. But if I have a lot of properties, then I get this error:
Error: The incoming request has too many parameters. The server supports a maximum of 2100 parameters. Reduce the number of parameters and resend the request.
Is there a better way to do this?
Thanks to #MarcGravell's suggestion, I decided to rewrite my query as a TVP query.
SQL:
create type AnimalInfo as table
(
AnimalTypeID int,
AnimalColorID int
)
go
C#:
public async Task<IEnumerable<Animal>> GetAnimalsFromAttributesAsync(DataTable attributeSets)
{
using (var myDB = new SqlConnection(connectionString))
{
await myDB.OpenAsync();
var sql = #"select AnimalID, AnimalTypeID, AnimalColor
from Animals
inner join #animalInfos animalInfos on
animalInfos.AnimalColorID = Animals.ColorID
and
animalInfos.AnimalTypeID = Animals.AnimalTypeID";
var result = await myDB.QueryAsync<Animal>(sql, new { animalInfos = attributeSets.AsTableValuedParameter("AnimalInfo") };
return result;
}
}

Map projection result with mongodb C# driver

I need to map to a simplified document some documents in a collection.
I can obtain what I need with this in the mongo shell:
db.getCollection('items').aggregate([
{ "$project": {
"Team": "$TeamId",
"Marker": "$Properties.marker.Value"
}}
])
I need to obtain the same result with C# driver (version 2.3.0); I tried this
var aggregation = m_database.GetCollection<BsonDocument>("items").Aggregate();
var projectionDefinition = new BsonDocument("$project", new BsonDocument
{
{ "Team", "$TeamId"},
{ "Marker", "$Properties.marker.Value" }
});
var query = aggregation.Project(projectionDefinition);
var result = await query.ToListAsync();
but I get the following error
Command aggregate failed: $expressions are not allowed at the top-level of $project
Someone kwons what's going on?
if you call Project you do have already $project in your bson,
so you just simplify your projectionDefinition:
var projectionDefinition = new BsonDocument
{
{ "Team", "$TeamId"},
{ "Marker", "$Properties.marker.Value" }
};
My personal opinion: I would avoid using pure bson, MongoDB driver gives you possibilities to use your c# dto classes for it.

How can I get NHibernate.Search FT query to use a "free text" query style?

I'm trying to implement a text search option using the Lucene-based full-text search engine on my NHibernate-based MVC project (NHibernate.Search). All the documentation I've seen on how to do this suggests I need to look at specific columns for values, something like:
var query = "Title:Ford";
using (var search = NHibernate.Search.Search.CreateFullTextSession(s))
{
using (var transaction = s.BeginTransaction())
{
var carSearchResults = search.CreateFullTextQuery(query)
.SetMaxResults(5)
.List();
foreach(var car in carSearchResults)
{
Console.WriteLine(car.Title);
}
transaction.Commit();
}
}
I would rather look at all full-text indexed columns for the search string, like you can do in SQL with a wildcard on the FREETEXT function... so I could do something like:
var query = "Ford";
using (var search = NHibernate.Search.Search.CreateFullTextSession(s))
{
using (var transaction = s.BeginTransaction())
{
var carSearchResults = search.CreateFullTextQuery(query)
.SetMaxResults(5)
.List();
foreach(var car in carSearchResults)
{
Console.WriteLine(car.Title);
}
transaction.Commit();
}
}
... and this would examine all full-text indexed properties for "Ford", and return all hits. Is there a comparable function/ method/ syntax for this using the NHibernate-based search engine?
Take a look at How to incorporate multiple fields in QueryParser?
Short answer, change:
var query = "Title:Ford";
to:
var query = "Title:Ford OR Name:Ford OR Field1:Ford OR Field2:Ford"; // etc for all fields

Categories