Всем доброго времени суток:
Использую последнюю версию haystack (2.4.1) и solr 4ой версии (если необходимо, могу узнать точную версию, но мне кажется, что это не критично).
Настроил фасетный поиск, так выглядит индекс
class SouvenirProductIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
category_title = indexes.CharField(model_attr='base_product__subcategory__category__title', faceted=True)
baseproduct_title = indexes.CharField(model_attr='base_product__title', faceted=True)
subcategory_title = indexes.CharField(model_attr='base_product__subcategory__title', faceted=True)
people_categories = indexes.MultiValueField(faceted=True)
holidays = indexes.MultiValueField(faceted=True)
colors = indexes.MultiValueField(faceted=True)
suggestions = indexes.FacetCharField()
def get_model(self):
return SouvenirProduct
def prepare_people_categories(self, obj):
return [people.style for people in obj.people_categories.all()]
def prepare_holidays(self, obj):
return [holiday.slug for holiday in obj.holidays.all()]
def prepare_colors(self, obj):
colors = []
for product_color in obj.productcolor_set.all():
color = product_color.color
if color.image:
colors.append(color.image.url)
else:
colors.append(color.rgb)
return colors
Вьюха:
class ProductSearchView(FacetedSearchView):
template_name = 'search/search.html'
form_class = FacetedNotEmptySearchForm
facet_fields = ['people_categories', 'holidays', 'category_title', 'colors']
Форма унаследована от FacetedSearchForm, изменения не влияют на мой вопрос.
В итоге у меня товары находятся по запросам, фасеты также выводятся (категории, например), но, если я выберу несколько категорий, то поиск пытается найти товар, который принадлежал бы все этим выбранным категориям (метод AND), а мне надо, чтобы он отдал те товары, которые принадлежат хотя бы одной из выбранных категорий(метод OR). Как это можно сделать?
файл schema.xml
<?xml version="1.0" ?>
<schema name="default" version="1.5">
<types>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>
<fieldtype name="binary" class="solr.BinaryField"/>
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" sortMissingLast="true" positionIncrementGap="0"/>
<fieldType name="float" class="solr.TrieFloatField" precisionStep="0" omitNorms="true" sortMissingLast="true" positionIncrementGap="0"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true" sortMissingLast="true" positionIncrementGap="0"/>
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" sortMissingLast="true" positionIncrementGap="0"/>
<fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/>
<fieldType name="tint" class="solr.TrieIntField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="date" class="solr.TrieDateField" omitNorms="true" precisionStep="0" positionIncrementGap="0"/>
<fieldType name="tdate" class="solr.TrieDateField" omitNorms="true" precisionStep="6" positionIncrementGap="0"/>
<fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
<fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
<fieldtype name="geohash" class="solr.GeoHashField"/>
<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" enablePositionIncrements="true" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="spell_ru" class="solr.TextField" positionIncrementGap="100" omitNorms="true">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.HunspellStemFilterFactory" dictionary="ru_RU.dic" affix="ru_RU.aff" ignoreCase="true" />
</analyzer>
</fieldType>
<fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
</analyzer>
</fieldType>
<fieldType name="ngram" class="solr.TextField" >
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="15" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<fieldType name="edge_ngram" class="solr.TextField" positionIncrementGap="1">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
</analyzer>
</fieldType>
</types>
<fields>
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="django_ct" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="django_id" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="_version_" type="long" indexed="true" stored ="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true"/>
<dynamicField name="*_t" type="spell_ru" indexed="true" stored="true"/>
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
<dynamicField name="*_p" type="location" indexed="true" stored="true"/>
<dynamicField name="*_coordinate" type="tdouble" indexed="true" stored="false"/>
<field name="text" type="spell_ru" indexed="true" stored="true" multiValued="false" />
<field name="holidays" type="spell_ru" indexed="true" stored="true" multiValued="true" />
<field name="category_title" type="spell_ru" indexed="true" stored="true" multiValued="false" />
<field name="category_title_exact" type="string" indexed="true" stored="true" multiValued="false" />
<field name="subcategory_title" type="spell_ru" indexed="true" stored="true" multiValued="false" />
<field name="subcategory_title_exact" type="string" indexed="true" stored="true" multiValued="false" />
<field name="baseproduct_title" type="spell_ru" indexed="true" stored="true" multiValued="false" />
<field name="baseproduct_title_exact" type="string" indexed="true" stored="true" multiValued="false" />
<field name="people_categories" type="spell_ru" indexed="true" stored="true" multiValued="true" />
<field name="suggestions" type="spell_ru" indexed="true" stored="true" multiValued="false" />
<field name="colors" type="spell_ru" indexed="true" stored="true" multiValued="true" />
<field name="colors_exact" type="string" indexed="true" stored="true" multiValued="true" />
<field name="people_categories_exact" type="string" indexed="true" stored="true" multiValued="true" />
<field name="holidays_exact" type="string" indexed="true" stored="true" multiValued="true" />
</fields>
<uniqueKey>id</uniqueKey>
<defaultSearchField>text</defaultSearchField>
<solrQueryParser defaultOperator="OR"/>
</schema>