我使用JSON通过HTTP / POST从C#/ Winforms / .NET4.0应用程序写入Solr,以加快索引并使用下面的代码。我写了一个文件给solr(基于这些instructions),但一直收到'400错误的请求'。 JSON似乎很干净,没有任何问题。
这似乎是一个语法问题,但我在最后几个小时一直在努力解决这个问题。关于什么是错误的任何想法?所有帮助表示赞赏。
这是发布的URI字符串
"http://localhost:8080/solr/update/json -H 'Content-type:application/json' -d ' [ {\"UUID\":\"d2a174e4-81d6-487f-b68d-392be5d3d47a\",\"Extension\":\".AVI\",\"VideoFileName\":\"Clip 1.avi\"} ' ]"
string uri = http://localhost:8080/solr/update/json;
public bool WriteJSONToSolr(string uri, string json)
{
WebRequest request = WebRequest.Create(uri + " -H 'Content-type:application/json' -d ' [ " + json + " ' ]" );
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(json);
Stream stream = null;
try
{ // send the Post
request.ContentLength = bytes.Length; //Count bytes to send
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length); //Send it
}
catch
{
return false;
}
finally
{
if (stream != null)
{
stream.Close();
}
}
System.Net.WebResponse response = request.GetResponse();
if (response == null) return false;
return true;
}
答案 0 :(得分:1)
如果要插入,则需要在json元素中使用add和doc。您还需要添加提交以便更新索引。您也可以从uri中删除参数,因为您可以在Web请求对象中添加它们。最后,您应该在uri中拥有您的集合名称。
string json = "{\"add\":{\"doc\":{"
+ "\"UUID\":\"d2a174e4-81d6-487f-b68d-392be5d3d47a\","
+ "\"Extension\":\".AVI\","
+ "\"VideoFileName\":\"Clip 1.avi\"}},";
+ "\"commit\":{}}";
string uri = "http://localhost:8080/solr/collection/update";
WebRequest request = WebRequest.Create(uri);
request.ContentType = "application/json";
request.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(json);
Stream stream = null;
try {
request.ContentLength = bytes.Length;
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
}
catch {
return;
}
finally {
if (stream != null) {
stream.Close();
}
}
System.Net.WebResponse response = request.GetResponse();
if (response == null) {
return;
}
如果要向solr插入多个对象,则可以向json添加多个添加对象或doc对象。例如......
json = "{add:{doc:{keys:values}}, add:{doc:{keys:values}}, commit:{}}"
或
json = "{add:{doc:{keys:values}, doc:{keys:values}}, commit:{}}"
在调试时,请查看solr的日志。它将提醒您解决可能在solr端发生的任何问题。
答案 1 :(得分:1)
首先,我不认为您使用-d选项传递正确的json数据。请查看代码中的以下格式代码。
" -H 'Content-type:application/json' -d ' [ " + json + " ' ]"
假设您的json数据为{"name":"sam"}
然后,上述格式化结果为
-H 'Content-type:application/json' -d ' [{"name":"sam"} ' ]
您正在传递缺少的json数据。
除此之外,您在solr索引中更新文档的方法是错误的。看看下面的简单代码。 [顺便说一句:你可以在网址中传递'commit'参数]。
public async Task PostAsync()
{
string json = "{\"add\": {\"doc\": {"
+ "\"id\":\"12345\","
+ "\"firstname\":\"Sam\","
+ "\"lastname\":\"Wills\","
+ "\"dob\":\"2016-12-14T00:00:00Z\""
+ "}}}";
using (var client = new HttpClient())
{
string uri = "http://localhost:8983/solr/people/update/json?wt=json&commit=true";
var jsonContent = new StringContent(json);
await client.PostAsync(new Uri(uri), jsonContent);
}
}
如果您想更新特定字段而不是整个文档[部分更新],请使用以下代码段。
public async Task PartialPostAsync()
{
string json = "{\"add\": {\"doc\": {"
+ "\"id\":\"12345\","
+ "\"lastname\":{\"set\":\"George\"}"
+ "}}}";
using (var client = new HttpClient())
{
string uri = "http://localhost:8983/solr/people/update/json?wt=json&commit=true";
var jsonContent = new StringContent(json);
await client.PostAsync(new Uri(uri), jsonContent);
}
}
'id'字段是一个唯一字段。
答案 2 :(得分:0)
你忘了在space
之前放一个-H
字符吗?
答案 3 :(得分:0)
我今天遇到了同样的问题。
尝试这两件事
1)请记住,你不能发送像
这样的json字符串[{"A":"1","B":"0","C":"","D":"Washington"}]
相反,你可能需要按摩json更像
[{"A":"1","B":"0","D":"Washington"}]
Solr不喜欢空值。
2)第二个技巧有助于(通过' curl '向solr发送数据时):在向solr发送请求之前,尝试用两个双引号替换json字符串中的所有双引号。
json = json.Replace(@"""", @"""""");
答案 4 :(得分:0)
您的代码无效的原因是因为您在.Net中使用cURL语法。
cURL是一个发送和接收HTTP请求的可执行文件,而.Net是一个编程应用程序的框架。
它们不一样。
要使它与.Net一起使用,您首先应该发布到正确的uri,并且您需要设置正确的ContentType属性,如下所示:
var uri = "http://localhost:8080/solr/update/json";
using (var r = WebRequest.Create(uri))
{
r.ContentType = "application/json";
r.Method = "POST";
using (var rs = r.GetRequestStream())
rs.Write // your data
// get response
// return response data
}
那说,为什么要给自己造成痛苦?只需使用已有Sold操作类型API的SolR连接器!
例如https://code.google.com/p/solrnet/!
但如果您不想使用它,那么至少要使用像https://nuget.org/packages/RestSharp这样的现代HTTP API
答案 5 :(得分:0)
将json转换为流字节后,请尝试以下代码
protected override void Append(LoggingEvent loggingEvent)
{
byte[] bodyBytes;
try
{
string body = BodyFormatter.CreateBody(loggingEvent, _parameters);
bodyBytes = Encoding.UTF8.GetBytes(body);
}
catch (Exception e)
{
ErrorHandler.Error("Failed to create body", e);
return;
}
HttpWebRequest request = BuildRequest();
request.BeginGetRequestStream(r =>
{
try
{
using (Stream stream = request.EndGetRequestStream(r))
{
stream.BeginWrite(bodyBytes, 0, bodyBytes.Length, c =>
{
try
{
stream.EndWrite(c);
request.BeginGetResponse(a =>
{
try
{
var response = request.EndGetResponse(a);
if (((HttpWebResponse)response).StatusCode != HttpStatusCode.OK)
ErrorHandler.Error("Got failed response: " + ((HttpWebResponse)response).StatusDescription);
response.Close();
}
catch (Exception e)
{
ErrorHandler.Error("Failed to get response", e);
}
}, null);
}
catch (Exception e)
{
ErrorHandler.Error("Failed to write", e);
}
}, null);
}
}
catch (Exception e)
{
ErrorHandler.Error("Failed to connect", e);
}
}, null);
}