通过HTTP / Post将JSON写入Solr

时间:2012-07-06 02:36:18

标签: c# json rest solr

我使用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;
        }

6 个答案:

答案 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);
}