I trying to work with django-haystack(2.6.0) and solr(4.10.4) to implement two fields search. I would like to search my model by ship
name or ship country
(returns a list of ships from a given country) but here I have a problem if I define one field with document=True
I get no results.
I fallowed the documentation and this answer and it looks fairly easy.
I have created the following search_indexes.py
:
class ShipListIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
return ShipList
def index_queryset(self, using=None):
return self.get_model().objects.all()
and I created a new template inside my app that specifies all the fields to be used in a search:
search/indexes/myapp/shiplist_text.txt
{{ objects.ship }}
{{ objects.country }}
so here it's my model:
class ShipList(models.Model):
ship = models.CharField(max_length=200)
country = models.CharField(max_length=200)
region = models.CharField(max_length=250, blank=True)
city = models.CharField(max_length=250, blank=True)
ship_class = models.CharField(max_length=200, blank=True)
ship_type = models.CharField(max_length=200, blank=True)
remarks = models.CharField(max_length=200, blank=True)
url = models.URLField(max_length=200)
slug = models.SlugField()
and the view:
def ship_search(request):
results = None
cd = None
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(ShipList).filter(content=cd['query']).load_all()
return render(request,
'core/draft/search.html',
{'form': form,
'results': results,
'cd': cd})
simple template
{% block search %}
{% if "query" in request.GET %}
{% for result in results %}
{% with ship=result.object %}
<p>{{ ship.ship }}</p>
<p><a href="{{ ship.get_absolute_url }}">{{ ship.ship }}</a></p>
{% endwith %}
{% empty %}
<p>There are no results for your query.</p>
{% endfor %}
{% else %}
<h1>Search for posts</h1>
<form action="." method="get">
{{ form.as_p }}
<input type="submit" value="Search">
</form>
{% endif %}
{% endblock %}
so then I've checked solr interface http://127.0.0.1:8983/solr/#/myapp/query
for JSON response:
{
"responseHeader": {
"status": 0,
"QTime": 2
},
"response": {
"numFound": 11,
"start": 0,
"docs": [
{
"django_ct": "core.shiplist",
"id": "core.shiplist.1",
"django_id": "1",
"text": "\n\n"
},
{
"django_ct": "core.shiplist",
"id": "core.shiplist.2",
"django_id": "2",
"text": "\n\n"
},
{
"django_ct": "core.shiplist",
"id": "core.shiplist.3",
"django_id": "3",
"text": "\n\n"
]
}
}
so this is the data stored for each ship in the search index
and I found out that the text field contains "\n\n
I'm guessing here is the problem maybe it should look like this:
"text": "USS Arizona\nUnited States"
so far I've tried to create search_indexs.py without use_template
:
class ShipListIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, model_attr='ship')
def get_model(self):
return ShipList
and it's working fine, I can search by ship name and the query output is correct.
{
"id": "core.shiplist.5",
"django_ct": "core.shiplist",
"django_id": "5",
"text": "USS Arizona"
},
and at last my solrconfig.xml
<?xml version="1.0" encoding="utf-8" ?>
<config>
<luceneMatchVersion>LUCENE_36</luceneMatchVersion>
<requestHandler name="/select" class="solr.StandardRequestHandler"
default="true" />
<requestHandler name="/update" class="solr.UpdateRequestHandler" />
<requestHandler name="/admin" class="solr.admin.AdminHandlers" />
<requestHandler name="/admin/ping" class="solr.PingRequestHandler">
<lst name="invariants">
<str name="qt">search</str>
<str name="q">*:*</str>
</lst>
</requestHandler>
</config>
Obviously I'm missing something or I don't understand how it works?
In your template for how the search field should be formed:
search/indexes/myapp/shiplist_text.txt
{{ objects.ship }}
{{ objects.country }}
.. you're referencing objects
(with an s at the end). The correct name is object
, without the extra s
:
{{ object.ship }}
{{ object.country }}
The extra \n you're seeing is the newline at the end of the file. Save it without that and you'll avoid having an extra \n at the end of your value as well. It doesn't really matter for searchability, though.