我有以下结构...让我们说商店里的产品。产品有评级。然后,用户可以(自行)对产品进行评分。假设 300k 产品加上 50k 用户评分(针对每个产品)
问题 1:子文档是正确的选择吗?我正在使用 SolrJ 添加所有内容,我没有找到任何其他合适的方法来做到这一点。
为了举例说明,您可以将以下代码复制并粘贴到集合中:
<add>
<doc>
<field name="id">1</field>
<field name="title" >Product Title LOLO</field>
<field name="content_type" >parent</field>
<field name="rating_f" >7</field>
<doc>
<field name="id">1</field>
<field name="user_id_s" >123</field>
<field name="userrating_f" >1.2</field>
</doc>
</doc>
<doc>
<field name="id">2</field>
<field name="title" >Product Title LULU</field>
<field name="content_type" >parent</field>
<field name="rating_f" >2</field>
</doc>
<doc>
<field name="id">3</field>
<field name="title" >Product Title LALA</field>
<field name="content_type" >parent</field>
<field name="rating_f" >1.4</field>
<doc>
<field name="id">1</field>
<field name="user_id_s" >123</field>
<field name="userrating_f" >5</field>
</doc>
</doc>
</add>
问题 2(重要问题):我现在如何查询此索引,以便首先对文档进行用户评分(如果存在),然后按产品评级(然后按其他字段,如创建日期、浏览量、购买量等)进行评分?这可能吗?
我正在研究类似的东西:
{!parent which="content_type:parent"}(user_id_s:123 AND _val_:userrating_f)^2.0 _val_:rating_f^2.0 *:*
这应该按以下顺序返回文档 (ids):3、1、2
但相反,它返回:
{
"responseHeader": {
"status": 500,
"QTime": 1,
"params": {
"indent": "true",
"q": "{!parent which="content_type:parent"}(user_id_s:123 AND _val_:userrating_f)^2.0 _val_:rating_f^2.0 *:*",
"_": "1421996862814",
"wt": "json"
}
},
"error": {
"msg": "child query must only match non-parent docs, but parent docID=3 matched childScorer=class org.apache.lucene.search.DisjunctionSumScorer",
"trace": "java.lang.IllegalStateException: child query must only match non-parent docs, but parent docID=3 matched childScorer=class org.apache.lucene.search.DisjunctionSumScorerntat org.apache.lucene.search.join.ToParentBlockJoinQuery$BlockJoinScorer.nextDoc(ToParentBlockJoinQuery.java:344)ntat org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll(Weight.java:192)ntat org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:163)ntat org.apache.lucene.search.BulkScorer.score(BulkScorer.java:35)ntat org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:621)ntat org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:297)ntat org.apache.solr.search.SolrIndexSearcher.buildAndRunCollectorChain(SolrIndexSearcher.java:209)ntat org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:1619)ntat org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:1433)ntat org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:514)ntat org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:485)ntat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:218)ntat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)ntat org.apache.solr.core.SolrCore.execute(SolrCore.java:1967)ntat org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:777)ntat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:418)ntat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:207)ntat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1419)ntat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)ntat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)ntat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)ntat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)ntat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)ntat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)ntat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)ntat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)ntat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)ntat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)ntat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)ntat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)ntat org.eclipse.jetty.server.Server.handle(Server.java:368)ntat org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)ntat org.eclipse.jetty.server.BlockingHttpConnection.handleRequest(BlockingHttpConnection.java:53)ntat org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:942)ntat org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1004)ntat org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:640)ntat org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)ntat org.eclipse.jetty.server.BlockingHttpConnection.handle(BlockingHttpConnection.java:72)ntat org.eclipse.jetty.server.bio.SocketConnector$ConnectorEndPoint.run(SocketConnector.java:264)ntat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)ntat org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)ntat java.lang.Thread.run(Thread.java:745)n",
"code": 500
}
}
- 有 SolrInputDocument.getChildrenDocs() 集合。
- 若要将分数从子查询传播到父查询,您需要 https://issues.apache.org/jira/browse/SOLR-5882
- 问题是函数查询与每个文档匹配,因此它违反了正交性并导致异常。 与
+content_type:child
相交子项查询