replacing opensearch with solr
This commit is contained in:
129
solr/stories/conf/managed-schema
Executable file
129
solr/stories/conf/managed-schema
Executable file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Solr Schema for StoryCove Stories Core
|
||||
Based on StorySearchDto data model
|
||||
-->
|
||||
<schema name="storycove-stories" version="1.6">
|
||||
|
||||
<!-- Field Types -->
|
||||
|
||||
<!-- String field type for exact matching -->
|
||||
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
|
||||
|
||||
<!-- Text field type for full-text search -->
|
||||
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
|
||||
<filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
<!-- Enhanced text field for titles and important content -->
|
||||
<fieldType name="text_enhanced" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
<!-- Integer field type -->
|
||||
<fieldType name="pint" class="solr.IntPointField" docValues="true"/>
|
||||
|
||||
<!-- Long field type -->
|
||||
<fieldType name="plong" class="solr.LongPointField" docValues="true"/>
|
||||
|
||||
<!-- Double field type -->
|
||||
<fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>
|
||||
|
||||
<!-- Boolean field type -->
|
||||
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
|
||||
|
||||
<!-- Date field type -->
|
||||
<fieldType name="pdate" class="solr.DatePointField" docValues="true"/>
|
||||
|
||||
<!-- Multi-valued string for tags and faceting -->
|
||||
<fieldType name="strings" class="solr.StrField" sortMissingLast="true" multiValued="true" docValues="true"/>
|
||||
|
||||
<!-- Single string for exact matching and faceting -->
|
||||
<fieldType name="string_facet" class="solr.StrField" sortMissingLast="true" docValues="true"/>
|
||||
|
||||
<!-- Fields -->
|
||||
|
||||
<!-- Required Fields -->
|
||||
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
|
||||
<field name="_version_" type="plong" indexed="false" stored="false"/>
|
||||
|
||||
<!-- Core Story Fields -->
|
||||
<field name="title" type="text_enhanced" indexed="true" stored="true" required="true"/>
|
||||
<field name="description" type="text_general" indexed="true" stored="true"/>
|
||||
<field name="sourceUrl" type="string" indexed="true" stored="true"/>
|
||||
<field name="coverPath" type="string" indexed="false" stored="true"/>
|
||||
<field name="wordCount" type="pint" indexed="true" stored="true"/>
|
||||
<field name="rating" type="pint" indexed="true" stored="true"/>
|
||||
<field name="averageStoryRating" type="pdouble" indexed="true" stored="true"/>
|
||||
<field name="volume" type="pint" indexed="true" stored="true"/>
|
||||
|
||||
<!-- Reading Status Fields -->
|
||||
<field name="isRead" type="boolean" indexed="true" stored="true"/>
|
||||
<field name="readingPosition" type="pint" indexed="true" stored="true"/>
|
||||
<field name="lastReadAt" type="pdate" indexed="true" stored="true"/>
|
||||
<field name="lastRead" type="pdate" indexed="true" stored="true"/>
|
||||
|
||||
<!-- Author Fields -->
|
||||
<field name="authorId" type="string" indexed="true" stored="true"/>
|
||||
<field name="authorName" type="text_enhanced" indexed="true" stored="true"/>
|
||||
<field name="authorName_facet" type="string_facet" indexed="true" stored="false"/>
|
||||
|
||||
<!-- Series Fields -->
|
||||
<field name="seriesId" type="string" indexed="true" stored="true"/>
|
||||
<field name="seriesName" type="text_enhanced" indexed="true" stored="true"/>
|
||||
<field name="seriesName_facet" type="string_facet" indexed="true" stored="false"/>
|
||||
|
||||
<!-- Tag Fields -->
|
||||
<field name="tagNames" type="strings" indexed="true" stored="true"/>
|
||||
<field name="tagNames_facet" type="strings" indexed="true" stored="false"/>
|
||||
|
||||
<!-- Timestamp Fields -->
|
||||
<field name="createdAt" type="pdate" indexed="true" stored="true"/>
|
||||
<field name="updatedAt" type="pdate" indexed="true" stored="true"/>
|
||||
<field name="dateAdded" type="pdate" indexed="true" stored="true"/>
|
||||
|
||||
<!-- Search-specific Fields -->
|
||||
<field name="searchScore" type="pdouble" indexed="false" stored="true"/>
|
||||
<field name="highlights" type="strings" indexed="false" stored="true"/>
|
||||
|
||||
<!-- Combined search field for general queries -->
|
||||
<field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
|
||||
|
||||
<!-- Copy Fields for comprehensive search -->
|
||||
<copyField source="title" dest="text"/>
|
||||
<copyField source="description" dest="text"/>
|
||||
<copyField source="authorName" dest="text"/>
|
||||
<copyField source="seriesName" dest="text"/>
|
||||
<copyField source="tagNames" dest="text"/>
|
||||
|
||||
<!-- Copy Fields for faceting -->
|
||||
<copyField source="authorName" dest="authorName_facet"/>
|
||||
<copyField source="seriesName" dest="seriesName_facet"/>
|
||||
<copyField source="tagNames" dest="tagNames_facet"/>
|
||||
|
||||
<!-- Default Search Field -->
|
||||
|
||||
<!-- UniqueKey -->
|
||||
<uniqueKey>id</uniqueKey>
|
||||
|
||||
</schema>
|
||||
153
solr/stories/conf/solrconfig.xml
Executable file
153
solr/stories/conf/solrconfig.xml
Executable file
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Solr Configuration for StoryCove Stories Core
|
||||
Optimized for story search with highlighting and faceting
|
||||
-->
|
||||
<config>
|
||||
<luceneMatchVersion>9.9.0</luceneMatchVersion>
|
||||
|
||||
<!-- DataDir configuration -->
|
||||
<dataDir>${solr.data.dir:}</dataDir>
|
||||
|
||||
<!-- Directory Factory -->
|
||||
<directoryFactory name="DirectoryFactory"
|
||||
class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
|
||||
|
||||
<!-- CodecFactory -->
|
||||
<codecFactory class="solr.SchemaCodecFactory"/>
|
||||
|
||||
<!-- Index Configuration -->
|
||||
<indexConfig>
|
||||
<lockType>${solr.lock.type:native}</lockType>
|
||||
<infoStream>true</infoStream>
|
||||
</indexConfig>
|
||||
|
||||
<!-- JMX Configuration -->
|
||||
<jmx />
|
||||
|
||||
<!-- Update Handler -->
|
||||
<updateHandler class="solr.DirectUpdateHandler2">
|
||||
<updateLog>
|
||||
<str name="dir">${solr.ulog.dir:}</str>
|
||||
<int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
|
||||
</updateLog>
|
||||
|
||||
<autoCommit>
|
||||
<maxTime>15000</maxTime>
|
||||
<openSearcher>false</openSearcher>
|
||||
</autoCommit>
|
||||
|
||||
<autoSoftCommit>
|
||||
<maxTime>1000</maxTime>
|
||||
</autoSoftCommit>
|
||||
</updateHandler>
|
||||
|
||||
<!-- Query Configuration -->
|
||||
<query>
|
||||
<maxBooleanClauses>1024</maxBooleanClauses>
|
||||
<filterCache class="solr.CaffeineCache"
|
||||
size="512"
|
||||
initialSize="512"
|
||||
autowarmCount="0"/>
|
||||
<queryResultCache class="solr.CaffeineCache"
|
||||
size="512"
|
||||
initialSize="512"
|
||||
autowarmCount="0"/>
|
||||
<documentCache class="solr.CaffeineCache"
|
||||
size="512"
|
||||
initialSize="512"
|
||||
autowarmCount="0"/>
|
||||
<enableLazyFieldLoading>true</enableLazyFieldLoading>
|
||||
</query>
|
||||
|
||||
<!-- Request Dispatcher -->
|
||||
<requestDispatcher handleSelect="false" >
|
||||
<requestParsers enableRemoteStreaming="true"
|
||||
multipartUploadLimitInKB="2048000"
|
||||
formdataUploadLimitInKB="2048"
|
||||
addHttpRequestToContext="false"/>
|
||||
<httpCaching never304="true" />
|
||||
</requestDispatcher>
|
||||
|
||||
<!-- Request Handlers -->
|
||||
|
||||
<!-- Standard Select Handler -->
|
||||
<requestHandler name="/select" class="solr.SearchHandler">
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">explicit</str>
|
||||
<int name="rows">10</int>
|
||||
<str name="df">text</str>
|
||||
<str name="wt">json</str>
|
||||
<str name="indent">true</str>
|
||||
<str name="hl">true</str>
|
||||
<str name="hl.fl">title,description</str>
|
||||
<str name="hl.simple.pre"><em></str>
|
||||
<str name="hl.simple.post"></em></str>
|
||||
<str name="hl.fragsize">150</str>
|
||||
<str name="hl.maxAnalyzedChars">51200</str>
|
||||
<str name="facet">true</str>
|
||||
<str name="facet.field">authorName</str>
|
||||
<str name="facet.field">tagNames</str>
|
||||
<str name="facet.field">seriesName</str>
|
||||
<str name="facet.field">rating</str>
|
||||
<str name="facet.field">isRead</str>
|
||||
<str name="facet.mincount">1</str>
|
||||
<str name="facet.sort">count</str>
|
||||
</lst>
|
||||
</requestHandler>
|
||||
|
||||
<!-- Update Handler -->
|
||||
<requestHandler name="/update" class="solr.UpdateRequestHandler" />
|
||||
|
||||
<!-- Admin Handlers -->
|
||||
<requestHandler name="/admin/ping" class="solr.PingRequestHandler">
|
||||
<lst name="invariants">
|
||||
<str name="q">*:*</str>
|
||||
</lst>
|
||||
<lst name="defaults">
|
||||
<str name="echoParams">all</str>
|
||||
</lst>
|
||||
</requestHandler>
|
||||
|
||||
<!-- More Like This Handler -->
|
||||
<requestHandler name="/mlt" class="solr.MoreLikeThisHandler">
|
||||
<lst name="defaults">
|
||||
<str name="mlt.fl">title,description</str>
|
||||
<int name="mlt.mindf">2</int>
|
||||
<int name="mlt.mintf">2</int>
|
||||
<str name="mlt.qf">title^2.0 description^1.0</str>
|
||||
<int name="rows">5</int>
|
||||
</lst>
|
||||
</requestHandler>
|
||||
|
||||
<!-- Suggester Handler -->
|
||||
<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
|
||||
<lst name="defaults">
|
||||
<str name="suggest">true</str>
|
||||
<str name="suggest.count">10</str>
|
||||
</lst>
|
||||
<arr name="components">
|
||||
<str>suggest</str>
|
||||
</arr>
|
||||
</requestHandler>
|
||||
|
||||
<!-- Search Components -->
|
||||
<searchComponent name="suggest" class="solr.SuggestComponent">
|
||||
<lst name="suggester">
|
||||
<str name="name">storySuggester</str>
|
||||
<str name="lookupImpl">AnalyzingInfixLookupFactory</str>
|
||||
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
|
||||
<str name="field">title</str>
|
||||
<str name="weightField">rating</str>
|
||||
<str name="suggestAnalyzerFieldType">text_general</str>
|
||||
<str name="buildOnStartup">false</str>
|
||||
<str name="buildOnCommit">false</str>
|
||||
</lst>
|
||||
</searchComponent>
|
||||
|
||||
<!-- Response Writers -->
|
||||
<queryResponseWriter name="json" class="solr.JSONResponseWriter">
|
||||
<str name="content-type">application/json; charset=UTF-8</str>
|
||||
</queryResponseWriter>
|
||||
|
||||
</config>
|
||||
34
solr/stories/conf/stopwords.txt
Executable file
34
solr/stories/conf/stopwords.txt
Executable file
@@ -0,0 +1,34 @@
|
||||
# English stopwords for story search
|
||||
a
|
||||
an
|
||||
and
|
||||
are
|
||||
as
|
||||
at
|
||||
be
|
||||
but
|
||||
by
|
||||
for
|
||||
if
|
||||
in
|
||||
into
|
||||
is
|
||||
it
|
||||
no
|
||||
not
|
||||
of
|
||||
on
|
||||
or
|
||||
such
|
||||
that
|
||||
the
|
||||
their
|
||||
then
|
||||
there
|
||||
these
|
||||
they
|
||||
this
|
||||
to
|
||||
was
|
||||
will
|
||||
with
|
||||
16
solr/stories/conf/synonyms.txt
Executable file
16
solr/stories/conf/synonyms.txt
Executable file
@@ -0,0 +1,16 @@
|
||||
# Synonyms for story search
|
||||
# Format: word1,word2,word3 => synonym1,synonym2
|
||||
fantasy,magical,magic
|
||||
sci-fi,science fiction,scifi
|
||||
romance,romantic,love
|
||||
mystery,detective,crime
|
||||
adventure,action
|
||||
horror,scary,frightening
|
||||
drama,dramatic
|
||||
comedy,funny,humor
|
||||
thriller,suspense
|
||||
historical,history
|
||||
contemporary,modern
|
||||
short,brief
|
||||
novel,book
|
||||
story,tale,narrative
|
||||
Reference in New Issue
Block a user