简体   繁体   English

使用solr中的函数进行过滤和排序

[英]Filtering and sorting using a function in solr

I have documents that look like this: 我的文档看起来像这样:

{attr_a: 1}, {attr_a: 2, changes_user1_a: 3}

Second document says that user1 made a change that is not yet "committed" and not visible to other users. 第二个文档说user1进行了一项尚未“提交”且其他用户无法看到的更改。

The fields are dynamic: 这些字段是动态的:

<dynamicField name="changes_*" type="string" indexed="true" stored="true"/>
<dynamicField name="attr_*" type="string" indexed="true" stored="true"/>

The thing is, user1 needs to do filtering, paging and sorting taking into account his new values, while other users need to do it on the old values. 问题是,user1需要考虑他的新值进行过滤,分页和排序,而其他用户需要对旧值进行过滤,分页和排序。

I was thinking of resolving this problem the following way: if user1 wants to filter and sort by attr_a, I would issue a query like 我想通过以下方式解决这个问题:如果user1想要按attr_a过滤和排序,我会发出一个类似的查询

fq=def(changes_user1_a, attr_a): 'somefilter'&sort=def(changes_user1_a, attr_a) asc

However, this approach generates the following error for fq: 但是,此方法会为fq生成以下错误:

"error":{
"metadata":[
  "error-class","org.apache.solr.common.SolrException",
  "root-error-class","org.apache.solr.parser.ParseException"],
"msg":"org.apache.solr.search.SyntaxError: Cannot parse 'def(changes_user1_a, attr_a): 3': Encountered \" \":\" \": \"\" at line 1, column 28.\r\nWas expecting one of:\r\n    <EOF> \r\n    <AND> ...\r\n    <OR> ...\r\n    <NOT> ...\r\n    \"+\" ...\r\n    \"-\" ...\r\n    <BAREOPER> ...\r\n    \"(\" ...\r\n    \"*\" ...\r\n    \"^\" ...\r\n    <QUOTED> ...\r\n    <TERM> ...\r\n    <PREFIXTERM> ...\r\n    <WILDTERM> ...\r\n    <REGEXPTERM> ...\r\n    \"[\" ...\r\n    \"{\" ...\r\n    <LPARAMS> ...\r\n    \"filter(\" ...\r\n    <NUMBER> ...\r\n    ",
"code":400}

And when sorting only, this one: 当排序时,这一个:

error":{
"trace":"java.lang.UnsupportedOperationException\r\n\tat org.apache.lucene.queries.function.FunctionValues.doubleVal(FunctionValues.java:47)\r\n\tat org.apache.lucene.queries.function.ValueSource$ValueSourceComparator.copy(ValueSource.java:153)\r\n\tat org.apache.lucene.search.TopFieldCollector$SimpleFieldCollector$1.collect(TopFieldCollector.java:206)\r\n\tat org.apache.lucene.search.MatchAllDocsQuery$1$1.score(MatchAllDocsQuery.java:56)\r\n\tat org.apache.lucene.search.BulkScorer.score(BulkScorer.java:39)\r\n\tat org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:669)\r\n\tat org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:473)\r\n\tat org.apache.solr.search.SolrIndexSearcher.buildAndRunCollectorChain(SolrIndexSearcher.java:260)\r\n\tat org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:1810)\r\n\tat org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:1627)\r\n\tat org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:643)\r\n\tat org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:529)\r\n\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:293)\r\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:156)\r\n\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:2036)\r\n\tat org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:657)\r\n\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:464)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:257)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:208)\r\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)\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:1160)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)\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:1092)\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.server.Server.handle(Server.java:518)\r\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308)\r\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)\r\n\tat org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:246)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:156)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)\r\n\tat java.lang.Thread.run(Thread.java:745)\r\n",
"code":500}

Although fl=test:def(changes_user1_a, attr_a) works like I would expect. 虽然fl=test:def(changes_user1_a, attr_a)就像我期望的那样工作。

So my questions would be: 所以我的问题是:

  1. Am I taking the right approach in solving this problem? 我是否采取了正确的方法来解决这个问题?
  2. If yes, why can't I sort and filter with the def function? 如果是,为什么我不能使用def函数进行排序和过滤?

I am using Solr version 6.1.0 我正在使用Solr版本6.1.0

Thanks 谢谢

For a filter with a function you have to use the frange parser. 对于具有函数过滤器,您必须使用frange解析器。 See eg: solr: Create filter query with a function . 请参阅eg: solr:使用函数创建过滤器查询

For example following query will return all docs having changes_user1_a=3 , or attr_a=3 if changes_user1_a field doesn't exist. 例如下面的查询将返回具有的所有文档changes_user1_a=3 ,或attr_a=3 ,如果changes_user1_a字段不存在。

fq={!frange u=3 l=3}def(changes_user1_a, attr_a)

Your sorting command seems ok to me, but it apparently doesn't work for string fields . 您的排序命令对我来说似乎没问题,但它显然不适用于字符串字段 I can reproduce your exception. 我可以重现你的异常。 It woks when both the fields are numeric. 当两个字段都是数字时,它就会出现问题。 Maybe bug in solr? 也许是solr中的bug?

 null:java.lang.UnsupportedOperationException
    at org.apache.lucene.queries.function.FunctionValues.doubleVal(FunctionValues.java:47)
    at org.apache.lucene.queries.function.valuesource.DefFunction$1.doubleVal(DefFunction.java:88)
    at org.apache.lucene.queries.function.ValueSource$ValueSourceComparator.copy(ValueSource.java:264)
    at org.apache.lucene.search.TopFieldCollector$SimpleFieldCollector$1.collect(TopFieldCollector.java:141)
    at org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll(Weight.java:246)
    at org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:197)
    at org.apache.lucene.search.BulkScorer.score(BulkScorer.java:39)
    at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:669)
    at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:473)
    at org.apache.solr.search.SolrIndexSearcher.buildAndRunCollectorChain(SolrIndexSearcher.java:225)
    at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:2027)
    at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:1844)
    at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:609)
 ...

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM