【发布时间】:2018-07-24 11:22:59
【问题描述】:
我正在尝试在 Elasticsearch 中建立父子关系,并且在尝试索引父级时始终从服务器收到空指针异常。
我在 6.2 版本中都使用 Elasticsearch 和 NEST。
我基本上一直在遵循文档中的本指南:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/parent-child-relationships.html
对象:(ESDocument是基类,ESVendor是父类,ESLocation是子类)
[ElasticsearchType(Name = "Doc", IdProperty = "Id")]
public abstract class ESDocument
{
public int Id { get; set; }
public JoinField MyJoinField { get; set; }
}
[ElasticsearchType(Name = "Vendor", IdProperty = "ConsigneeID")]
public class ESVendor: ESDocument
{
public int VendorID { get; set; }
public int VendorTypeID { get; set; }
public int ClientID { get; set; }
public int CompanyID { get; private set; }
public int LocationID { get; set; }
public bool Active { get; set; }
public TimeSpan? OpenTime { get; set; }
public TimeSpan? CloseTime { get; set; }
public bool AppointmentRequired { get; set; }
public decimal? Latitude { get; set; }
public decimal? Longitude { get; set; }
public bool PositionRequested { get; set; }
public bool PositionFailed { get; set; }
public int? NoteID { get; set; }
public int? OldID { get; set; }
public ESVendor(Vendor vendor)
{
if (vendor == null)
{
return;
}
Id = vendor.VendorID;
CompanyID = vendor.CompanyID;
Active = vendor.Active;
VendorID = vendor.VendorID;
Latitude = vendor.Latitude;
Longitude = vendor.Longitude;
VendorTypeID = vendor.VendorTypeID;
ClientID = vendor.ClientID;
LocationID = vendor.LocationID;
Latitude = vendor.Latitude;
OpenTime = vendor.OpenTime;
CloseTime = vendor.CloseTime;
AppointmentRequired = vendor.AppointmentRequired;
PositionRequested = vendor.PositionRequested;
PositionFailed = vendor.PositionFailed;
NoteID = vendor.NoteID;
OldID = vendor.OldID;
}
public ESVendor()
{
}
}
[ElasticsearchType(Name = "Location", IdProperty = "LocationID")]
public class ESLocation: ESDocument
{
public int LocationID { get; set; }
public int CompanyID { get; private set; }
public string Name { get; set; }
public string Address { get; set; }
public string Address2 { get; set; }
public string CityStateZipCountry { get; set; }
public string Note { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
public ESLocation(Location location)
{
if (location == null)
{
return;
}
Id = location.LocationID;
CompanyID = location.CompanyID;
Address = location.Address;
Address2 = location.Address2;
LocationID = location.LocationID;
Name = location.Name;
Note = location.Note;
City = location.City;
State = location.State;
Zip = location.Zip;
Country = location.Country;
CityStateZipCountry = location.Country + " " + location.State + " " + location.Zip + " " + location.Country;
}
public ESLocation()
{
}
}
映射+索引:
StaticConnectionPool connectionPool = new StaticConnectionPool(_nodes);
ConnectionSettings connectionSettings = new ConnectionSettings(connectionPool, sourceSerializer: SourceSerializer)
.DisableDirectStreaming()
.DefaultMappingFor<ESDocument>(m => m.IndexName("vendors").TypeName("doc"))
.DefaultMappingFor<ESVendor>(m => m.IndexName("vendors").TypeName("doc").RelationName("Vendor_Location"))
.DefaultMappingFor<ESLocation>(m => m.IndexName("vendors").TypeName("doc"));
ElasticClient esClient = new ElasticClient(connectionSettings);
IExistsResponse existsResponse = await esClient.IndexExistsAsync(new IndexExistsRequest(Indices.Parse("vendors")));
if (!existsResponse.Exists)
{
esClient.CreateIndex("vendors", c => c
.Index<ESVendor>()
.Mappings(ms => ms
.Map<ESVendor>(m => m
.RoutingField(r => r.Required())
.AutoMap<ESVendor>()
.AutoMap<ESLocation>()
.Properties(props => props
.Join(j => j
.Name(p => p.MyJoinField)
.Relations(r => r
.Join<ESVendor, ESLocation>()
)
)
)
)
));
}
using (Entities dbContext = new Entities())
{
foreach (Vendor vendor in dbContext.Vendors)
{
if (!(await esClient.DocumentExistsAsync(new DocumentExistsRequest("vendors", typeof (Vendor), vendor.VendorID))).Exists)
{
ESVendor parent = new ESVendor(vendor)
{
MyJoinField = JoinField.Root<ESVendor>()
};
var result = esClient.IndexDocument<ESDocument>(parent);
ESLocation child = new ESLocation(vendor.Location)
{
MyJoinField = JoinField.Link<ESLocation, ESVendor>(parent)
};
result = esClient.IndexDocument<ESDocument>(child);
}
}
}
每次尝试索引父文档时,它都会始终返回以下错误。
Invalid NEST response built from a unsuccessful low level call on POST: /vendors/doc
# Audit trail of this API call:
- [1] BadResponse: Node: http://192.168.50.240:9200/ Took: 00:00:00.2060485
# OriginalException: Elasticsearch.Net.ElasticsearchClientException: The remote server returned an error: (500) Internal Server Error.. Call: Status code 500 from: POST /vendors/doc. ServerError: Type: null_pointer_exception Reason: "id must not be null" ---> System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
at System.Net.HttpWebRequest.GetResponse()
at Elasticsearch.Net.HttpConnection.Request[TResponse](RequestData requestData)
--- End of inner exception stack trace ---
# Request:
{"vendorID":1,"vendorTypeID":1,"clientID":349,"companyID":1,"locationID":4994,"active":true,"openTime":null,"closeTime":null,"appointmentRequired":false,"latitude":null,"longitude":null,"positionRequested":false,"positionFailed":false,"noteID":null,"oldID":1626,"id":1,"myJoinField":"Vendor_Location"}
# Response:
{"error":{"root_cause":[{"type":"null_pointer_exception","reason":"id must not be null"}],"type":"null_pointer_exception","reason":"id must not be null"},"status":500}
我已经为此奋斗了好几天,本来应该是 30 分钟的任务,但我已经束手无策了。
提前感谢您,非常感谢您的帮助!
【问题讨论】:
-
你使用的是什么版本的 NEST 包,你的目标是什么版本的 Elasticsearch?您能否将详细信息添加到您的问题中
-
我在 6.3 都使用 Elasticsearch 和 NEST。我在 6.2 中遇到了同样的问题,所以我更新了想法,也许这会有所帮助。
-
最新的 NEST 版本是 6.2.0 - 你在使用 Elasticsearch 6.3.0 吗?
-
抱歉,它们都是 6.2,最近从 6.1 更新。我不在办公室,从记忆中提取了版本。
标签: c# .net elasticsearch nest