Closed liguobao closed 1 year ago
@liguobao Based on the errors like:
{
"type": "mapper_parsing_exception",
"reason": "failed to parse field [join] of type [text] in document with id '37cb21f9-fcaf-4a1c-ae9e-6887f7a6e972'. Preview of field's value: '{parent=452e6028-5665-40ad-9b8e-aed105015852, name=strategy}'",
"caused_by": {
"type": "illegal_state_exception",
"reason": "Can't get text on a START_OBJECT at 1:9"
}
}
It appears your index already exists but has an incorrect mapping, assuming this is not in production use yet have you tried removing the index and allowing it to be recreated by the code? As running your code locally for me works as expected.
If you go to http://{dashboards_url}:5601/app/dev_tools
and run GET /book-indexer/_mapping
you should get something like below:
{
"book-indexer": {
"mappings": {
"_routing": {
"required": true
},
"properties": {
"id": {
"type": "keyword"
},
"isPay": {
"type": "boolean"
},
"join": {
"type": "join",
"eager_global_ordinals": true,
"relations": {
"book-base": "stop-notice"
}
},
"lastChapterTime": {
"type": "date"
},
"pricingStrategyId": {
"type": "keyword"
},
"seriesBookJoinTime": {
"type": "date"
},
"seriesId": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"seriesOrder": {
"type": "integer"
},
"strategyId": {
"type": "keyword"
},
"tags": {
"type": "keyword"
}
}
}
}
}
Notice how the join
property has "type": "join"
with the relation information, however I expect in your case it will have "type": "text"
.
For reference the exact code I ran was:
using OpenSearch.Client;
using OpenSearch.Net;
using System.Text.RegularExpressions;
public static class Program
{
public static async Task Main(string[] args)
{
var client = new OpenSearchDemoClient();
await client.CreateBookDocumentAsync(new OpenEsBookBaseDemo
{
Id = Guid.NewGuid().ToString(),
IsPay = false,
LastChapterTime = DateTime.Parse("2019-06-13T16:56:40"),
StrategyId = Guid.NewGuid().ToString(),
Tags = new[] { "tag1", "tag2" }
}, new OpenEsBookStopNoticeDemo
{
Id = Guid.NewGuid().ToString()
});
}
}
public interface IOpenBookDocumentDemo
{
/// <summary>
/// Id
/// </summary>
string Id { get; set; }
/// <summary>
/// Join
/// </summary>
JoinField Join { get; set; }
}
/// <summary>
///
/// </summary>
[OpenSearchType(RelationName = "book-base")]
public class OpenEsBookBaseDemo : IOpenBookDocumentDemo
{
public string Id { get; set; }
/// <summary>
///
/// </summary>
public bool IsPay { get; set; }
/// <summary>
///
/// </summary>
public string[] Tags { get; set; }
#region
/// <summary>
///
/// </summary>
public string StrategyId { get; set; }
/// <summary>
///
/// </summary>
public string PricingStrategyId { get; set; }
/// <summary>
///
/// </summary>
public DateTime? LastChapterTime { get; set; }
#endregion
/// <summary>
/// Join
/// </summary>
public JoinField Join { get; set; }
public string SeriesId { get; set; }
public int? SeriesOrder { get; set; }
/// <summary>
/// 系列与书的关联时间
/// </summary>
public DateTime? SeriesBookJoinTime { get; set; }
}
/// <summary>
///
/// </summary>
[OpenSearchType(RelationName = "stop-notice")]
public class OpenEsBookStopNoticeDemo : IOpenBookDocumentDemo
{
public string Id { get; set; }
/// <summary>
/// Join
/// </summary>
public JoinField Join { get; set; }
}
public class OpenSearchDemoClient
{
private OpenSearchClient _elasticClient;
private readonly Regex _esQueryRegex;
private readonly string BookIndexer = "book-indexer";
private readonly string ESHost = "https://localhost:9200";
private readonly string ElasticUser = "admin";
private readonly string ElasticPassword = "admin";
public OpenSearchDemoClient()
{
_elasticClient = InitElasticClient(ESHost, ElasticUser, ElasticPassword);
_esQueryRegex = new Regex(@"(?:\w+\:\*(?<word>.*?)\*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
private OpenSearchClient InitElasticClient(string elasticHost, string elasticUser, string elasticPassword)
{
var pool = new SingleNodeConnectionPool(new Uri(elasticHost));
var connSettings =
new OpenSearch.Client.ConnectionSettings(pool,
OpenSearch.Client.JsonNetSerializer.JsonNetSerializer.Default);
if (!string.IsNullOrEmpty(elasticUser) && !string.IsNullOrEmpty(elasticPassword))
{
connSettings.BasicAuthentication(elasticUser, elasticPassword);
}
connSettings.ServerCertificateValidationCallback(CertificateValidations.AllowAll);
connSettings.DisableDirectStreaming();
return new OpenSearchClient(connSettings);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private async Task CreateIndexAsync()
{
var existsRep = await _elasticClient.Indices.ExistsAsync(BookIndexer);
if (existsRep.ApiCall.HttpStatusCode == 200)
return;
var response = await _elasticClient.Indices.CreateAsync(
BookIndexer, c => c
.Map<IOpenBookDocumentDemo>(m => m
.RoutingField(r => r.Required())
.AutoMap<OpenEsBookBaseDemo>()
.AutoMap<OpenEsBookStopNoticeDemo>()
.Properties(props => props
.Join(j => j
.Name(p => p.Join)
.Relations(r => r
.Join<OpenEsBookBaseDemo, OpenEsBookStopNoticeDemo>()
)
)
.Keyword(s => s.Name(f => f.Id))
)
.Properties<OpenEsBookBaseDemo>(props => props
.Keyword(s => s.Name(f => f.StrategyId))
.Keyword(
s => s.Name(f => f.PricingStrategyId))
.Keyword(s => s.Name(f => f.Tags))
)
)
);
if (!response.IsValid)
{
Console.WriteLine($"create indexer failed. debug info: {response.DebugInformation}");
}
}
/// <summary>
///
/// </summary>
/// <param name="book"></param>
/// <param name="children"></param>
/// <returns></returns>
public virtual async Task CreateBookDocumentAsync(OpenEsBookBaseDemo book, params IOpenBookDocumentDemo[] children)
{
await CreateIndexAsync();
book.Join = JoinField.Root<OpenEsBookBaseDemo>();
Func<BulkDescriptor, IBulkRequest> descriptor = s => s.Index<IOpenBookDocumentDemo>(i
=> i.Document(book)).Index(BookIndexer);
if (children != null && children.Any(x => x != null))
{
children = children.Where(x => x != null).ToArray();
foreach (var child in children)
child.Join = JoinField.Link(RelationName.Create(child.GetType()), book.Id);
descriptor = s =>
s.Index<IOpenBookDocumentDemo>(i => i.Document(book)).IndexMany(children)
.Index(BookIndexer);
}
var response = await _elasticClient.BulkAsync(descriptor);
if (!response.IsValid)
Console.WriteLine($"create indexer failed. debug info: {response.DebugInformation}");
}
}
What is the bug?
I try to migration "elastis 6.8.14" to OpenSearch 2.3.0 Version,
use Mapping func createIndex, the server response 400 err.
Error like it.
How can one reproduce the bug?
My Code
How I fix it? Thanks~