I am new to Elasticsearch and NEST etc. using c#. So, far I have learned and managed to write a code to create an index but the problem is how do I create a second table (type). If I create it the same way then it only creates one table and not the second one.
Code:
public static void CreateIndex()
{
ConnectionSettings settings = new ConnectionSettings(new Uri("http://localhost:9200"));
settings.DefaultIndex("store");
ElasticClient client = new ElasticClient(settings);
client.Indices.Delete(Indices.Index("store"));
var indexSettings = client.Indices.Exists("store");
if (!indexSettings.Exists)
{
var response = client.Indices.Create(Indices.Index("store"));
}
}
public static void CreateSeed()
{
int seedValue = 1;
int limitValue = 20000;
IList<stores> List = new List<stores>();
ConnectionSettings settings = new ConnectionSettings(new Uri("http://localhost:9200"));
settings.DefaultIndex("store");
ElasticClient esClient = new ElasticClient(settings);
var item = new store() { ID = seedValue, Title = "item" + seedValue.ToString(), IsPublished = true };
var response = esClient.IndexAsync(item, idx => idx.Index("store"));
}
/// <summary>
///
/// </summary>
public static void CreateMappings()
{
ConnectionSettings settings = new ConnectionSettings(new Uri("http://localhost:9200"));
settings.DefaultIndex("store");
ElasticClient esClient = new ElasticClient(settings);
esClient.Map<stores>(m =>
{
var putMappingDescriptor = m.Index(Indices.Index("store")).AutoMap();
return putMappingDescriptor;
});
}
This create a store index and can be retrieved. However, if I create another table of different name e.g. itemsstore the same way, the older one doesn't exist anywhere.
Why? How do I create a new second table?
Looking at the example given, it looks like this will
delete "store" index
check if the "store" index exists (it won't as it was just deleted)
create a "store" index
set the default index to use as the "store" index (which will be created on indexing the first document, if it doesn't exist)
index store types into a "store" index
create a mapping for the "store" index
In summary, the example looks like it only interacts with a "store" index.
A simple example to create two indices is
var client = new ElasticClient();
var createIndexResponse = await client.Indices.CreateAsync("store");
if (!createIndexResponse.IsValid)
{
// take some action e.g. logging, exception, etc.
// To keep the example simple, just throw an exception
throw new Exception(createIndexResponse.DebugInformation);
}
createIndexResponse = await client.Indices.CreateAsync("itemsstore");
if (!createIndexResponse.IsValid)
{
throw new Exception(createIndexResponse.DebugInformation);
}
The walkthrough on building a Nuget search web application may be useful. The different branches have walkthroughs for different version of the client. For example, the 7.x branch is for NEST 7.x, with 7.x-codecomplete showing the completed example. It'll demonstrate a number of Elasticsearch and search related concepts.
Related
I can create a database and container without an issue on both gremlin and sql, ut I can't seem to set the partition key.
I would expect to do
///
var containerParams = new SqlContainerCreateUpdateParameters
(
new SqlContainerResource(databaseName)
{
PartitionKey = new ContainerPartitionKey()
{
Paths = new List<string>{partialKey}
}
},
new CreateUpdateOptions()
)
///
I would expect to do something like this, but the Paths field is readonly, and I can't see any other option to set it.
[Update]
i got it working with creating an object then converting to json and back to ContainerPartitionKey
Here is the syntax for creating the partition key using Cosmos DB Azure Management SDK.
SqlContainerCreateUpdateParameters sqlContainerCreateUpdateParameters = new SqlContainerCreateUpdateParameters
{
Resource = new SqlContainerResource
{
Id = containerName,
DefaultTtl = -1, //-1 = off, 0 = on no default, >0 = ttl in seconds
AnalyticalStorageTtl = -1,
PartitionKey = new ContainerPartitionKey
{
Kind = "Hash",
Paths = new List<string> { "/myPartitionKey" },
Version = 1 //version 2 for large partition key
}
}
You can find a complete SqlContainer create example here. You can also find a complete set of examples for how to use the Azure Management SDK for Cosmos DB in GitHub. Please note, it is out of date but should still work for illustrating how to use to manage Cosmos resources.
I'm creating a new customer and adding them to a subscription in one call like so:
StripeConfiguration.SetApiKey(StripeData.ApiKey);
var customerService = new CustomerService();
var myCustomer = new CustomerCreateOptions
{
Email = stripeEmail,
Source = stripeToken,
Plan = StripeData.MonthlySubscriptionPlanId
};
Customer stripeCustomer = customerService.Create(myCustomer);
Then I used to be able to do this:
myLocalUser.StripeCustomerId = stripeCustomer.Id;
myLocalUser.StripeSubscriptionId = stripeCustomer.Subscriptions.Data[0]?.Id;
But now the API isn't returning the customer's subscriptions so the second line fails
I'm now having to call the API again with this ugly code to get the customer's subscriptionId:
if (stripeCustomer.Subscriptions != null)
{
user.StripeSubscriptionId = stripeCustomer.Subscriptions.Data[0]?.Id;
}
else
{
//get subscriptionId
var cust = customerService.Get(stripeCustomer.Id, new CustomerGetOptions
{
Expand = new System.Collections.Generic.List<string> { "subscriptions" }
});
if (cust.Subscriptions.Any())
{
stripeSubscriptionId = cust.Subscriptions.First().Id;
}
}
CustomerService.Create() doesn't have the same Expand parameter option that the Get() method does...
This is expected, as subscriptions are no longer included by default on a customer object unless you expand them since API version 2020-08-27.
Creating a customer with a source and plan is still possible (although not the recommended integration path anymore since you might run into problems with 3DS and tax rates), although since you are on a newer API version you won't get the subscriptions list back. If you can you should update to creating subscriptions via their own API.
If you however still want to use this old integration path, you can still get the subscriptions back in the customer create call, you just need to expand the subscriptions on creation:
var customerService = new CustomerService();
var myCustomer = new CustomerCreateOptions
{
Email = stripeEmail,
Source = stripeToken,
Plan = StripeData.MonthlySubscriptionPlanId
};
myCustomer.AddExpand("subscriptions");
Customer stripeCustomer = customerService.Create(myCustomer);
I am trying to get the total count of api keys in my API gateway via SDK.
However I am unsure on the proper implementation of the parameters that the GetApiKeysRequest takes in. My main objective is to get the count of all API keys that are already existing for my account.
The code I have so far looks like this :
class Program
{
public static void Main(string[] args)
{
var awsUserAccessKey = "xxxxx";
var awsUserSecretKey = "yyyyyyyyyyy";
var regionEndpoint = "us-west-2";
var keysInRepository = new GetApiKeysRequest
{
CustomerId = "",
IncludeValues = true||false,
Limit=0,
NameQuery = "",
Position = ""
};
var client = new AmazonAPIGatewayClient(awsUserAccessKey, awsUserSecretKey, regionEndpoint);
var apiKeys =client.GetApiKeys(keysInRepository);
Console.Read();
}
}
This code throws an error saying that The security token included in the request is invalid (Amazon.APIGateway exception).I am unsure on how to set the parameters for this request.
Because the AmazonAPIGatewayClient you are using as described here takes three string arguments and the last one is awsSessionToken i think you are confusing with this one which takes as third argument RegionEndpoint
Do something like that instead :
var client = new AmazonAPIGatewayClient(awsUserAccessKey, awsUserSecretKey, RegionEndpoint.USWest2);
For someone looking for a solution to similar problems, this worked :
var awsUserAccessKey = "xxxx";
var awsUserSecretKey = "yyyyy";
var regionEndpointName = "us-west-2";
var regionEndpoint = RegionEndpoint.GetBySystemName(regionEndpointName);
var keysInRepository = new GetApiKeysRequest
{
Limit = 500
};
//define the key and its fields
var client = new AmazonAPIGatewayClient(awsUserAccessKey, awsUserSecretKey, regionEndpoint);
var apiKeys = client.GetApiKeys(keysInRepository);
Console.WriteLine("Current number of api keys:{0}", apiKeys.Items.Count);
I have an application with index called zzz and I indexed few documents into the index.
string configvalue1 = ConfigurationManager.AppSettings["http://localhost:9200/"];
var pool = new SingleNodeConnectionPool(new Uri(configvalue1));
var defaultIndex = "zzz";
**settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.MapDefaultTypeNames(m => m.Add(typeof(Class1), "type"))
.PrettyJson()
.DisableDirectStreaming();
client = new ElasticClient(settings);**
if (client.IndexExists(defaultIndex).Exists && ConfigurationManager.AppSettings["syncMode"] == "Full")
{
client.DeleteIndex(defaultIndex);
client.CreateIndex(defaultIndex);
}
return client;
Now in an entire new application, i have to check if zzz is existing or not and just use it for some search operation. Do I still have to write everything that is in between ** in the above code or just connect to the pool and check for index?
Here is my take:
configvalue1 = ConfigurationManager.AppSettings["http://localhost:9200/"];
var pool = new SingleNodeConnectionPool(new Uri(configvalue1));
settings = new ConnectionSettings(pool);
client = new ElasticClient(settings);
// to check if the index exists and return if exist
if (client.IndexExists("zzz").Exists)
{
return client;
}
Just adding to the above question:
I want to implement some condition like this before indexing:
Index doesnt exist && sync mode == full --> Create index
Index exist && sync mode==full --> Delete old index and create a new
Index doesnt exist && sync mode == new --> Create index
Index exist && sync mode==new --> Use the existing index
TIA
You would need at a minimum
string configvalue1 = ConfigurationManager.AppSettings["http://localhost:9200/"];
var pool = new SingleNodeConnectionPool(new Uri(configvalue1));
var defaultIndex = "zzz";
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
if (!client.IndexExists(defaultIndex).Exists &&
ConfigurationManager.AppSettings["syncMode"] == "Full")
{
// do something when the index is not there. Maybe create it?
}
If you're going to be using Class1 in this application and don't want to specify the type for it on all requests then add
.MapDefaultTypeNames(m => m.Add(typeof(Class1), "type"))
to connection settings.
With
.PrettyJson()
this is useful for development purposes but I would not recommend using in production as all requests and responses will be larger as the json will be indented.
Similarly, with
.DisableDirectStreaming()
again, I would not recommend using this in production unless you have a need say to log all requests and responses from the application side; this setting causes all request and response bytes to be buffered in a MemoryStream so that they can be read outside of the client, for example, in OnRequestCompleted.
More details on the settings can be found in the documentation.
I've programmatically created a new document collection using the MongoDB C# driver.
At this point I want to create and build indexes programmatically. How can I do that?
Starting from v2.0 of the driver there's a new async-only API. The old API should no longer be used as it's a blocking facade over the new API and is deprecated.
The currently recommended way to create an index is by calling and awaiting CreateOneAsync with an IndexKeysDefinition you get by using Builders.IndexKeys:
static async Task CreateIndexAsync()
{
var client = new MongoClient();
var database = client.GetDatabase("HamsterSchool");
var collection = database.GetCollection<Hamster>("Hamsters");
var indexKeysDefinition = Builders<Hamster>.IndexKeys.Ascending(hamster => hamster.Name);
await collection.Indexes.CreateOneAsync(new CreateIndexModel<Hamster>(indexKeysDefinition));
}
you should use CreateIndex as EnsureIndex is marked obsolete for future compatibility with the next versions of MongoDB:
var client = new MongoClient("mongodb://localhost");
var db = client.GetServer().GetDatabase("db");
var collection = db.GetCollection<Hamster>("Hamsters");
collection.CreateIndex(IndexKeys<Hamster>.Ascending(_ => _.Name));
The overload of CreateOneAsync in the currently accepted answer is now marked as obsolete with the message "Use CreateOneAsync with a CreateIndexModel instead." Here's how you do it:
static async Task CreateIndex(string connectionString)
{
var client = new MongoClient(connectionString);
var database = client.GetDatabase("HamsterSchool");
var collection = database.GetCollection<Hamster>("Hamsters");
var indexOptions = new CreateIndexOptions();
var indexKeys = Builders<Hamster>.IndexKeys.Ascending(hamster => hamster.Name);
var indexModel = new CreateIndexModel<Hamster>(indexKeys, indexOptions);
await collection.Indexes.CreateOneAsync(indexModel);
}
Something like this should do:
var server = MongoServer.Create("mongodb://localhost");
var db = server.GetDatabase("myapp");
var users = db.GetCollection<User>("users");
users.EnsureIndex(new IndexKeysBuilder().Ascending("EmailAddress"));
Please see the following bits in the documentation:
http://api.mongodb.org/csharp/current/html/06bcd201-8844-3df5-d170-15f2b423675c.htm
There is an entire area on Indexing under the Definitions and Builders documentation page:
http://mongodb.github.io/mongo-csharp-driver/2.4/reference/driver/definitions/#index-keys
Example:
IndexKeysDefinition<MyModel> keys = "{ Reference: 1 }";
var indexModel = new CreateIndexModel<MyModel>(keys);
await _context.Indexes.CreateOneAsync(indexModel);
the easiest way to create indexes in c# is by using the driver wrapper library MongoDB.Entities. here's an example of creating a text index:
DB.Index<Author>()
.Key(a => a.Name, Type.Text)
.Key(a => a.Surname, Type.Text)
.Create();
and to do a full-text search, you simply do:
DB.SearchText<Author>("search term");
haven't seen anything else that makes it simpler than that.