Add compound Index to MongoDB API in Cosmos - c#

I am using sorting in my application and using cosmos mongodb api as database. I have created wildcard index in the code to accommodate the sorting but somehow I am still getting the error as compound index is missing. Here is how I am creating the index.
var wcIndex = new IndexKeysDefinitionBuilder<T>().Wildcard();
var wcIndexModel = new CreateIndexModel<T>(wcIndex, options);
_collection = _database.GetCollection<T>(_collectionName);
_collection.Indexes.CreateOneAsync(wcIndexModel);
and the error am getting is
The index path corresponding to the specified order-by item is
excluded / The order by query does not have a corresponding composite
index that it can be served from.
Is there anyway I can add composite index for model to get the sorting done ?

I have added the below code to make it work for using sorting in mongo Cosmos API.
IndexKeysDefinition<T> keys = "{'$**': 1}";
var wildcardIndex = new CreateIndexModel<T>(keys);
_collection = _database.GetCollection<T>(_collectionName);
_collection.Indexes.CreateOne(wildcardIndex);

Related

How can I do a point read without knowing the partition key using .Net SDK V3?

I'm using AzureCosmos SDK3 and trying to fetch an item details from Cosmos db by using ReadItemAsync method. My container has got multiple Partition Key and while fetching data I do not want to specify Partition Key.
var item = container.ReadItemsAsync<T>(itemid, PartitionKey.None);
Specifying PartitionKey as None also not working.
You cannot do a point read if you do not know the Partition Key Value of the document.
The document's identity is the id and the Partition Key Value, you can have multiple documents with the same id but in different Partition Keys.
You can use GetItemQueryIterator it's required only query and it will fetch all the required data as per query.
e.g.
var query = container.GetItemQueryIterator<TestDoc>("SELECT * FROM c WHERE c.id = 'foo'");
while (query.HasMoreResults)
{
var doc = await query.ReadNextAsync();
foreach(var x in doc.Resource)
{
Console.WriteLine($"Retrieved document {x.Id}");
}
}

MongoDB search using text index not working c#

I have Added text index on my collection. I am trying to filter the data with text search with some additional filters. But It is not working well with other filters.
{$text:{$search:"test"},Type:"5"}
The above query returns all 42 entries matching the criteria from mongoDB Atlas.
But when I am doing this from c# I think I am querying it wrong. What am I missing here.
var collection = db.GetCollection<TestTbl>("TestTbl");
var filter = Builders<TestTbl>.Filter.Text(searchtext)
&Builders<TestTbl>.Filter.Eq("TypeID", TypeID);
var data = collection.Find(filter).ToList();
here data is returned null.
When I am giving text only in the filter it works fine.
{$text:{$search:"test"}}
var collection = db.GetCollection<TestTbl>("TestTbl");
var filter = Builders<TestTbl>.Filter.Text(searchtext);
var data = collection.Find(filter).ToList();
The Error was with my model it was Guid Type forgot to mention the bsontype string for the field representation

How do I a grab a parameter within a document MONGODB (C#)

i have the following problem, i filtered the collection to get the specific document in collection which i need. The document inside it has some variable with some values. How do i grab the specific variable and its value from the specific document.
MongoClient client = new MongoClient();
var db = client.GetDatabase("myfirstdb");
var collection = db.GetCollection<PlayerInfo>("players");
var filter = Builders<PlayerInfo>.Filter.Eq("playerName", player.Name);
//find in document filter the parameter "isAdmin" and grab its value.
This is how my document looks like.
You have to use Project clause when you perform the find operation on the filter. Below code will do.
bool isAdmin = collection.Find(filter).Project(x => x.isAdmin).FirstOrDefault();

Searching for record in c# Winform (Entity Framework)

I have a c# winform with textboxes, connected via Entity Framework to a table, called Candidates (it has 700 records).
I'm using a BindingSource named candidatesBindingSource. Everything works as I want.
There is just one thing. I'm trying to implement searching candidates with surnames. So i have a Textbox, called textSurname and a Button with this code
for searching through my records:
var searchResults = (from a in _context.Candidates where (a.Surname.Contains(textSurname.Text)) select a.Id).ToList();
if (searchResults.Count > 0)
{
// Id of a record in searchResults is correct
var position = searchResults[0];
// This line moves focus to a wrong record
candidatesBindingSource.Position = position; //
}
If a record is found, I can get its Id. And here I have a problem. How can I reposition my candidatesBindingSource to the
record with the Id from my searchResults? For example, if I have an Id = 2638, the code above repositions my candidatesBindingSource
to the last record. I'm suspecting that this part candidatesBindingSource.Position actualy works as recordcount (700 in my table)
and is unable to go to the record nr. 2638 (not to the record with this Id). Am I right? So how can I implement a GOTO record with my found Id?
Do I really have to use a For loop with MoveNext command to compare my searched Id with all Id's?
Any hint would be very appreciated.
Ok, so this is how you initialize you binding source
candidatesBindingSource.DataSource = _context.Candidates.ToList();
Then you don't need to search the database, you can search the data source list using the List.FindIndex method like this:
var candidateList = (List<Candidate>)candidatesBindingSource.DataSource;
var searchText = textSurname.Text;
var firstMatchIndex = candidateList.FindIndex(c => c.Surname.Contains(searchText));
if (firstMatchIndex >= 0)
candidatesBindingSource.Position = firstMatchIndex;
I think you should set to candidatesBindingSource.Position index of item and not id.
That post will help you to get index of item correctly, witout read whole data again.
Get Row Index in a list by using entity framework
Also you can try get index from your binding source.
If you create a list out of your context it will have the same indexing as the databinding you set on your form. To set your form to look at the result of your search you can use the a match from the FindIndex() method of the list, and then set your .Position to that index.
using (Candidates _context = new Candidates())
{
var candidateList = _context.Candidate.ToList();
var firstCandidateMatchIndex = candidateList.FindIndex(c =>
c.Surname.Contains(textSurname.Text));
if (firstCandidateMatchIndex >= 0)
candidateBindingSource.Position = firstCandidateMatchIndex;
}

MongoDb bulk operation get id

I want to perform bulk operation via MongoDb. How to get array of Ids that will be returned after it?
Can i perform single-operation insert faster without using bulk ? Can you advise me some other approach ?
I'm using C# mongoDb driver 2.0 and MongoDb v. 3.0.2
update:
I found the following solution - save maximum ObjectId of mongo collection,
db.col.find().sort({_id:-1}).limit(1).pretty()
and do the same after insert
So we will get the range of inserted documents, does it make a sense?
You can insert items in bulk using the new driver with InsertManyAsync. If you want the Ids that the driver generated for these items you can simply get them out of the items themselves after they are inserted. For example:
Hamster[] hamsters = { new Hamster { Name = "Vaska" }, new Hamster { Name = "Petzka" } };
await collection.InsertManyAsync(hamsters);
var insertedIDs = hamsters.Select(_ => _.Id);

Categories