I have been trying to use to the bulk insert function but every time I use it is showing some mapping error . Has the bulk insert function declaration have changed from nest 1.x to nest 5.x because in 5.x nest documentation I did not find the .bulk() function . Please Suggest
Code for bulk insert:
public void bulkInsert(List<BaseData> recordList, List<String> listOfIndexName)
{
BulkDescriptor descriptor = new BulkDescriptor();
descriptor.Index<BaseData>(op => op
.Document(recordList[j])
.Index(listOfIndexName[j])
);
}
var result = clientConnection.Bulk(descriptor);
}
My list of data that I am passing looks something like this :
[ElasticsearchType(IdProperty = "number")]
class TicketData : BaseData
{
//[ElasticProperty(Index = FieldIndexOption.NotAnalyzed, Store = true)]
[Date(Name = "sys_updated_on", Store = true)]
public DateTimeOffset sys_updated_on { get; set; }
[Text(Name = "number", Store = true)]
public override string number { get; set; }
[Text(Name = "incident_state", Store = true)]
public string incident_state { get; set; }
[Text(Name = "location", Store = true)]
public string location { get; set; }
[Text(Name = "assigned_to", Store = true)]
public string assigned_to { get; set; }
[Text(Name = "u_knowledge_id", Store = true)]
public string u_knowledge_id { get; set; }
[Text(Name = "u_knowledge_id.u_process_role", Store = true)]
public string u_knowledge_id_u_process_role { get; set; }
}
It seems that NEST cannot infer the correct type of your entity because you specify generic type BaseData whereas the actual type is TicketData. You should specify the actual type of entity you want to index. Since you may have different types inside your list, you can get the actual type using GetType() method:
descriptor.Index<BaseData>(op => op
.Document(recordList[j])
.Index(listOfIndexName[j])
.Type(recordList[j].GetType())
);
Currently your query tries to dynamically create a different type with default mapping instead of interpreting it as existing type with explicit mapping
Related
I am developing a web api .I got the following error . same code structure working for fetchbyid ,post,edit . What did i wrong here . please help me.
Catalog.cs:
public class Catalog
{
[JsonProperty("id")]
public Guid? Id { get; set; }
[JsonProperty("VendorName")]
public string VendorName { get; set; }
// public List<Industy> Industy { get; set; }
public Industy Industy { get; set; }
public Catalog()
{
if (Id == null)
{
Id = Guid.NewGuid();
}
else
{
Id = Id;
}
// this.Industy = new List<Industy>();
}
}
public async Task<IEnumerable<Catalog>> FetchListAsync(
Guid? itemId)
{
var feedOptions =
new FeedOptions
{
MaxItemCount = -1,
EnableCrossPartitionQuery = true
};
var query = new SqlQuerySpec
{
QueryText = "SELECT * FROM c"
};
var orderDocumentQuery =
_cosmosClient.CreateDocumentQuery<Catalog>(
UriFactory.CreateDocumentCollectionUri(
_azureCosmosDbOptions.Value.DatabaseId, "catalog"), query, feedOptions)
.AsDocumentQuery();
var orderList =
new List<Catalog>();
Console.WriteLine(orderDocumentQuery.ToString());
while (orderDocumentQuery.HasMoreResults)
{
orderList.AddRange(
await orderDocumentQuery.ExecuteNextAsync<Catalog>());
}
return orderList;
}
error:
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CatalogAPI.Entities.Industy]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'Industy.Id', line 1, position 117.
What do i doing wrong??
The POCO object in Cosmos DB needs to have it's id field to be a string.
You need to replace public Guid? Id { get; set; } with public string Id { get; set; }.
Here is controller code
[EnableQuery]
public IQueryable<Product> Get()
{
var productRepository = new ProductRepository();
return productRepository.Retrieve().AsQueryable();
}
Here is Retrieve() method
internal List<Product> Retrieve()
{
var filePath = HostingEnvironment.MapPath(#"~/App_Data/product.json");
var json = System.IO.File.ReadAllText(filePath);
var products = JsonConvert.DeserializeObject<List<Product>>(json);
return products;
}
And Product class
public class Product
{
public string Description { get; set; }
public decimal Price { get; set; }
public string ProductCode { get; set; }
public int ProductId { get; set; }
public string ProductName { get; set; }
public DateTime ReleaseDate { get; set; }
}
Other filters like $filter=Price+gt+6 or $top=4 and $skip=1 work fine. WebApi.OData package version=5.7.0
Error:
"The query specified in the URI is not valid. An unknown function with name 'contains' was found.
substringof() is a V3 function while contains() is a V4 function.
Try contains:
$filter=contains(Name,'value')
You are probably using an OData library package for OData version 3, but contains is a version 4 function. You can either query with the substringof function defined in version 3, or switch to a package that supports OData version 4.
I have a document that contains an array of tags. I need to create a suggestion field corresponding to this tag field (to generate tag suggestions based on the values in the tag array). I am using NEST to interact with elastic search mostly. But I am not able to updated the suggestion property. The class used for the document contains following
Document structure:
public class SuggestField
{
public IEnumerable<string> Input { get; set; }
public string Output { get; set; }
public object Payload { get; set; }
public int? Weight { get; set; }
}
public class Source{
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
public string[] tags { get; set; }
public SuggestField[] tag_suggest { get; set; }
}
I add the mapping as follows:
var response = client.Map<Source>(m => m
.MapFromAttributes()
.Properties(p => p
.Completion(c => c
.Name(cp => cp.tag_suggest)
.Payloads()
)));
For updating tags, I use external scripts. I was hoping to change this same script to add changes to tag_suggest field also. But I tried the following but it is not working. Following is the script I tried:
if (ctx._source.tags.indexOf(newTag) < 0) {
ctx._source.tags[ctx._source.tags.length] = newTag;
ctx._source.tag_suggest[ctx._source.tag_suggest.length] = { input :newTag }
}
I would change type of tag_suggest property from SuggestField[] to SuggestField. You can store all tags in SuggestField.Input.
public class Source
{
[ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
public string[] tags { get; set; }
public SuggestField tag_suggest { get; set; }
}
Regarding your update script, after this change you can modify it to:
if (ctx._source.tags.indexOf(newTag) < 0) {
ctx._source.tags[ctx._source.tags.length] = newTag;
ctx._source.tag_suggest.input[ctx._source.tag_suggest.length] = newTag;
}
Hope it helps.
I'm trying to run an integer comparison (for instance greater than or less than) using OData on a value that is set to be a type of varchar in the database. Crossing out the solution of changing the database field to be a type of int, as it's not preferred in my specific case, is there a way to tell Telerik OpenAccess to convert the field to a type of integer when executing either the query or the mappings?
Thanks in advance.
It is similar with this one: Handling Dates with OData v4, EF6 and Web API v2.2
Add one more proerpty:
public partial class Title
{
public int Id { get; set; }
public string Name { get; set; }
public string StringProperty { get; set; }
}
public partial class Title
{
[NotMapped]
public int IntProperty
{
get
{
return StringProperty==null?0;Int32.Parse(StringProperty);;
}
set
{
StringProperty = value.ToString();
}
}
}
Update the model:
public static IEdmModel GetModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
EntityTypeConfiguration<Title> titleType= builder.EntityType<Title>();
titleType.Ignore(t => t.StringProperty);
titleType.Property(t => t.IntProperty ).Name = "MyProperty";
builder.EntitySet<Title>("Titles");
builder.Namespace = typeof(Title).Namespace;
return builder.GetEdmModel();
}
I'm using the mongo-csharp-driver to query my Mongo entities.
I have the following objects which are stored in the Mongo:
public class Table
{
public int Id { get; private set; }
public string Description{ get; private set; }
public List<Player> Players { get; private set; }
public Table()
{
}
}
public class Player
{
public int Id { get; private set; }
public string Username{ get; private set; }
public Player()
{
}
}
When I'm trying to query the "Table" object by id or description, I get the appropriate results, but when I try to query by the list of player, I get null:
// Works ok
var tab1 = mongo.GetCollection<Table>().Where(g => g.Description == "Test");
// Always return null, although should return the same result
var tab2 = mongo.GetCollection<Table>().Where(g => g.Players.Count > 90).FirstOrDefault();
What am I missing here?
Thanks,
Nir.
The issue is that Count property is translated into the $size query operator.
From the linked Advanced Queries page you can see that:
"You cannot use $size to find a range of sizes (for example: arrays
with more than 1 element)."