【问题标题】:Write JSON to Solr via HTTP/Post通过 HTTP/Post 将 JSON 写入 Solr
【发布时间】:2012-07-06 02:36:17
【问题描述】:

我正在通过 HTTP/POST 从 C#/Winforms/.NET4.0 应用程序使用 JSON 向 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;
        }

【问题讨论】:

  • 停止使用真/假作为控制流。
  • 你没有处理你的流,只是关闭它。
  • 不要捕获任何和所有异常,就像您第一次返回 false 时所做的那样。你也没有处理你的 WebRequest。

标签: c# json rest solr


【解决方案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 插入多个对象,您可以将多个 add 对象或 doc 对象添加到 json。比如……

json = "{add:{doc:{keys:values}}, add:{doc:{keys:values}}, commit:{}}"

json = "{add:{doc:{keys:values}, doc:{keys:values}}, commit:{}}"

在调试时,请查看 solr 的日志。它会提醒您 solr 方面可能发生的任何问题。

【讨论】:

    【解决方案2】:

    首先,我不认为您使用 -d 选项传递了正确的 json 数据。请查看代码中的以下格式化代码。

    " -H 'Content-type:application/json' -d ' [ " + json + " ' ]" 
    

    假设,你的json数据是{"name":"sam"}那么,上面的格式化结果为

    -H 'Content-type:application/json' -d ' [{"name":"sam"} ' ]
    

    您正在传递一个缺少 ] 的 json 数据。

    除此之外,您在 solr 索引中更新文档的方法是错误的。看看下面的简单代码。 [顺便说一句:您可以在 url 中传递 '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);
        }
    }
    

    如果要更新特定字段而不是整个文档[部分更新],请使用以下代码 sn-p。

    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”字段是唯一字段。

    【讨论】:

      【解决方案3】:

      您是否忘记在-H 之前添加space 字符?

      【讨论】:

      • 不幸的是,所有这些迭代都在之前添加了空间等等。没有运气:-(。顺便说一下,Solr 没有返回错误消息,或者只是一个 400 错误请求,InnerException 为空。谢谢
      • 但是为什么已经把json放到url里了,为什么还要发布json str呢?
      • 嗯..不确定这会有所不同。我正在尝试差异。组合。
      • 那么为什么不尝试做GetResponse()
      【解决方案4】:

      您的代码无法正常工作的原因是您在 .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
      }
      

      也就是说,为什么要让自己痛苦呢?只需使用已经为 SolR 操作提供类型化 API 的 SolR 连接器!

      例如https://code.google.com/p/solrnet/

      但如果您不想使用它,那么至少使用现代 HTTP API,例如 https://nuget.org/packages/RestSharp

      【讨论】:

        【解决方案5】:

        我今天遇到了同样的问题。

        试试这两件事

        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(@"""", @"""""");

        【讨论】:

          【解决方案6】:

          请在将 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);
          }
          

          【讨论】:

            猜你喜欢
            • 2018-01-16
            • 2011-04-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-06-12
            • 2019-04-12
            相关资源
            最近更新 更多