2015-01-23 2 views
1

У меня есть следующая структура ... позволяет говорить о продуктах в магазине. Продукты имеют рейтинг. Затем пользователи могут, кроме того, оценивать продукт (самостоятельно). Допустим, 300 тыс. Продуктов плюс 50 тыс. Пользовательских оценок (для каждого продукта)Оценка Solr на основе поддокумента (parent blockjoin)

Вопрос 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 *:* 

Это должно вернуть документы в таком порядке (идентификаторы): 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.DisjunctionSumScorer\n\tat org.apache.lucene.search.join.ToParentBlockJoinQuery$BlockJoinScorer.nextDoc(ToParentBlockJoinQuery.java:344)\n\tat org.apache.lucene.search.Weight$DefaultBulkScorer.scoreAll(Weight.java:192)\n\tat org.apache.lucene.search.Weight$DefaultBulkScorer.score(Weight.java:163)\n\tat org.apache.lucene.search.BulkScorer.score(BulkScorer.java:35)\n\tat org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:621)\n\tat org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:297)\n\tat org.apache.solr.search.SolrIndexSearcher.buildAndRunCollectorChain(SolrIndexSearcher.java:209)\n\tat org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:1619)\n\tat org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:1433)\n\tat org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:514)\n\tat org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:485)\n\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:218)\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:135)\n\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:1967)\n\tat org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:777)\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:418)\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:207)\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1419)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:455)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)\n\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)\n\tat org.eclipse.jetty.server.Server.handle(Server.java:368)\n\tat org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)\n\tat org.eclipse.jetty.server.BlockingHttpConnection.handleRequest(BlockingHttpConnection.java:53)\n\tat org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:942)\n\tat org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1004)\n\tat org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:640)\n\tat org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)\n\tat org.eclipse.jetty.server.BlockingHttpConnection.handle(BlockingHttpConnection.java:72)\n\tat org.eclipse.jetty.server.bio.SocketConnector$ConnectorEndPoint.run(SocketConnector.java:264)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)\n\tat java.lang.Thread.run(Thread.java:745)\n", 
     "code": 500 
    } 
    } 

ответ

3
  1. есть коллекция SolrInputDocument.getChildrenDocs() или так. используй это.
  2. для распространения оценки от детского запроса к родительским вам необходимо https://issues.apache.org/jira/browse/SOLR-5882
  3. проблема в том, что функциональные запросы соответствуют каждому документу, что нарушает ортогональность и вызывает исключение. пересекают детей с +content_type:child