2012-07-16 2 views
1

Что было бы хорошим дизайном для использования Solr для поиска в сложных JSON? Например там может быть документ, как:Solr дизайн для поиска в комплексе JSON

{ 
    "books" : [ 
     { 
      "title" : "Some title", 
      "author" : "Some author", 
      "genres" : [ 
       "thriller", 
       "drama" 
      ] 
     }, 
     { 
      "title" : "Some other title", 
      "author" : "Some author", 
      "genres" : [ 
       "comedy", 
       "nonfiction", 
       "thriller" 
      ] 
     } 
    ] 
} 

Пример запрос будет получить все документы, которые имеют книгу автор которой является «Некоторым автором» и один из жанров книги является «драмой».

Сейчас дизайн я придумал, чтобы иметь dynamicField в schema.xml, что индексы все как текст (на данный момент), например, так:

<dynamicField name="*" type="text" index="true" stored="true"/> 

Затем SolrJ используется для разбора JSON и создать SolrInputDocument с полями для каждой части данных. Например эти поля/значение, которые будут созданы для примера JSON выше:

books0.title : "Some title" 
books0.author : "Some author" 
books0.genres0 : "thriller" 
books0.genres1 : "drama" 
books1.title : "Some other title" 
books1.author : "Some author" 
books1.genres0 : "comedy" 
books1.genres1 : "nonfiction" 
books1.genres2 : "thriller" 

На данный момент мы могли бы использовать LukeRequestHandler, чтобы получить все поля в индексе, а затем сделать большой запрос Solr, что проверяет все интересующие нас поля. Для запроса запроса над запросом будут проверяться все поля «books # .author» и «books # .genres #». Это решение кажется неэлегантным, и запросы могут стать очень большими, если есть много полей.

Было бы полезно использовать подстановочные знаки в именах полей, но я не думаю, что это возможно с помощью Solr.

Есть ли лучший способ достичь этого, возможно, используя в схеме какую-нибудь умную комбинацию «copyField» и «multiValued»?

ответ

2

Вы можете проиндексировать объект книги как документы.

<field name="id" type="string" indexed="true" stored="true" required="true" /> 
<field name="title" type="text_general" indexed="true" stored="true"/> 
<!-- Don't perform stemming on authors - You can use field with lower case, ascii folding for analysis --> 
<field name="authors" type="string" indexed="true" stored="true" multiValued="true"/> 
<field name="genre" type="string" indexed="true" stored="true" multiValued="true"/> 

Использование Dismax parser поиск по авторам и жанрам.
Матч на этом поле должен вернуть вам документ.
Вы можете использовать жанр для фильтрации с помощью filter query, а также, например, fq = жанр: драма

Если вы хотите, чтобы поведение поиска отличалось для полей, вы можете просто использовать copyField, чтобы скопировать поля и провести другой анализ. , например.

<field name="genre_search" type="text_general" indexed="true" stored="true" multiValued="true"/> 

<copyField source="genre" dest="genre_search"/> 
+0

Вы имеете в виду, что каждая «книга» будет документом? – Thomas

+0

you отдельный документ. – Jayendra

+0

Я принял этот ответ, потому что привел меня к этому http://www.lucidimagination.com/search/document/93e8b09e90b0076c/help_with_denormalizing_issues#60890dcb99a3004d, который убедил меня, что каждый «объект» в JSON необходимо индексировать как собственный документ , – Thomas

0

Возможно, вам стоит посмотреть на Solr Joins. Он доступен только в 4.0, теперь по альфе, но может позволить вам смоделировать хотя бы часть или, возможно, все эти сложные отношения. Производительность не так хороша, как ванильный solr без соединений, но может быть совершенно верным, вы должны проверить.

Смежные вопросы