1

我正在通过 C#/Winforms/.NET4.0 应用程序中的 HTTP/POST 使用 JSON 向 Solr 写入数据,以加快索引和使用下面的代码。我向 solr 写了一个文档(基于这些说明),但不断收到“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;
        }
4

6 回答 6

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 方面可能发生的任何问题。

于 2015-01-20T19:18:23.053 回答
1

首先,我不认为您使用 -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);
    }
}

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

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

于 2016-01-23T17:46:57.850 回答
0

The reasong that your code isn't working, is because you are using cURL syntax in .Net.

cURL is an executable that sends and receives HTTP requests and .Net is a framework for programming applications.

They are not the same.

To make it work with .Net you first should post to the correct uri, and you need to set the correct ContentType property like such:

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
}

That said, why inflict pain upon yourself? Just use a SolR connector that already has a typed API for SolR operations!

https://code.google.com/p/solrnet/ for example!

But if you don't want to use that, then at least use a modern HTTP API like https://nuget.org/packages/RestSharp

于 2012-11-20T18:43:41.327 回答
0

你之前忘了放一个space字符-H吗?

于 2012-07-06T02:52:57.463 回答
0

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

试试这两件事

1)请记住,您不能发送像

[{"A":"1","B":"0","C":"","D":"Washington"}]

相反,您可能必须按摩 json 以使其更像

[{"A":"1","B":"0","D":"Washington"}]

Solr 不喜欢空值。

2)第二个有用的技巧(通过' curl '向solr发送数据时):在将请求发送到solr之前,尝试用两个双引号替换json字符串中的所有双引号。

json = json.Replace(@"""", @"""""");

于 2012-11-20T17:16:31.850 回答
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);
}
于 2020-01-30T12:08:47.283 回答