Solr Error: QueryComponent.mergeIds(QueryComponent.java:940) when using invariants in a request handler

Solr Error: QueryComponent.mergeIds(QueryComponent.java:940) when using invariants in a request handler

我需要一个仅 return 集合中一组特定字段的搜索请求处理程序,但出于安全原因,任何人都无法更改要显示的字段。 (有一些我不希望任何人访问的索引敏感字段)

我尝试在请求处理程序中使用 invariants,并在那里定义字段列表,所以我制作了一个这样的处理程序:

   <requestHandler class="solr.SearchHandler" name="/search">
    <lst name="defaults">
        <str name="q">*:*</str>
    </lst>
    <lst name="invariants">
        <str name="fl">content</str>
        <str name="fl">description</str>
    </lst>
  </requestHandler>

但是,当我调用请求处理程序时出现此错误:

{
  "responseHeader":{
    "zkConnected":true,
    "status":500,
    "QTime":4},
  "error":{
    "trace":"java.lang.NullPointerException\r\n\tat org.apache.solr.handler.component.QueryComponent.mergeIds(QueryComponent.java:940)\r\n\tat org.apache.solr.handler.component.QueryComponent.handleRegularResponses(QueryComponent.java:585)\r\n\tat org.apache.solr.handler.component.QueryComponent.handleResponses(QueryComponent.java:564)\r\n\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:423)\r\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:177)\r\n\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:2503)\r\n\tat org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:710)\r\n\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:516)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:382)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:326)\r\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1751)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\r\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)\r\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\r\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\r\n\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)\r\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\r\n\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\r\n\tat org.eclipse.jetty.server.Server.handle(Server.java:534)\r\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)\r\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)\r\n\tat org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:251)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)\r\n\tat org.eclipse.jetty.io.SelectChannelEndPoint.run(SelectChannelEndPoint.java:93)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:589)\r\n\tat java.lang.Thread.run(Unknown Source)\r\n",
    "code":500}}

目前我做了一个解决方法,将字段放在 default 中而不是 invariants 中。所以我让处理程序变成这样:

<requestHandler class="solr.SearchHandler" name="/search">
    <lst name="defaults">
        <str name="q">*:*</str>
        <str name="fl">content</str>
        <str name="fl">description</str>
    </lst>
  </requestHandler>

此变通办法有效,但我不希望这样做,因为它不够安全。任何人都可以帮忙吗? 有关其他信息,我使用的是 Solr 版本 7.2.1,并且该集合有 2 个分片,2 个副本。

当您将 fl 列表设置为 invariant 时,这意味着分片之间的内部请求也无法覆盖它。触发错误的行是:

resultIds.put(shardDoc.id.toString(), shardDoc);

我猜您希望在您的字段列表中包含 id,并且可能还包含 _version__root__version_ 在复制和乐观并发更新方面有特殊意义,而 _root_ 影响子文档。