Django-haystack: solr์„ ๋ฐฑ์—”๋“œ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ ๊ฒ€์ƒ‰์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2015๋…„ 05์›” 01์ผ  ยท  41์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: django-haystack/django-haystack

์ €๋Š” haystack์˜ ๋ฐฑ์—”๋“œ๋กœ solr์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ค€๋น„ ๋ช…๋ น(schema.xml ์ƒ์„ฑ ๋“ฑ)์„ ์ˆ˜ํ–‰ํ–ˆ์ง€๋งŒ ์ฒซ ๋ฒˆ์งธ ๊ฒ€์ƒ‰์„ ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚ด ํŒŒ์ด์ฌ ํ™˜๊ฒฝ์ž…๋‹ˆ๋‹ค.

Django==1.8
django-filter==0.9.2
django-haystack==2.3.1
djangorestframework==3.1.1
Markdown==2.6.1
Pillow==2.8.1
psycopg2==2.6
pysolr==3.3.0
requests==2.6.0

๋‚ด๊ฐ€ ๋งŒ๋‚œ ์˜ˆ์™ธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

'list' object has no attribute 'split'

solr์ด django_ct ํ•„๋“œ์— ๋Œ€ํ•œ ๋ชฉ๋ก์œผ๋กœ ์‘๋‹ตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ haystack์€ ๋ฌธ์ž์—ด์„ ๊ธฐ๋Œ€ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์Šคํƒ ์ถ”์ ์ž…๋‹ˆ๋‹ค.

Environment:


Request Method: GET
Request URL: http://localhost:8000/api/1.0/p/products/?search=test

Django Version: 1.8
Python Version: 3.4.0
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.gis',
 'rest_framework',
 'rest_framework.authtoken',
 'django_filters',
 'haystack',
 'deliveries',
 'products',
 'stores',
 'users')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Traceback:
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/views/decorators/csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
  452.             response = self.handle_exception(exc)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/rest_framework/views.py" in dispatch
  449.             response = handler(request, *args, **kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/rest_framework/generics.py" in get
  199.         return self.list(request, *args, **kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/rest_framework/mixins.py" in list
  41.         page = self.paginate_queryset(queryset)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/rest_framework/generics.py" in paginate_queryset
  170.         return self.paginator.paginate_queryset(queryset, self.request, view=self)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/rest_framework/pagination.py" in paginate_queryset
  299.             self.page = paginator.page(page_number)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/core/paginator.py" in page
  50.         number = self.validate_number(number)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/core/paginator.py" in validate_number
  39.         if number > self.num_pages:
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/core/paginator.py" in _get_num_pages
  86.             if self.count == 0 and not self.allow_empty_first_page:
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/django/core/paginator.py" in _get_count
  77.                 self._count = len(self.object_list)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/haystack/query.py" in __len__
  91.             self._result_count = self.query.get_count()
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/haystack/backends/__init__.py" in get_count
  626.                 self.run()
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/haystack/backends/solr_backend.py" in run
  699.         results = self.backend.search(final_query, **search_kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/haystack/backends/__init__.py" in wrapper
  35.             return func(obj, query_string, *args, **kwargs)
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/haystack/backends/solr_backend.py" in search
  136.         return self._process_results(raw_results, highlight=kwargs.get('highlight'), result_class=kwargs.get('result_class', SearchResult), distance_point=kwargs.get('distance_point'))
File "/home/nicolas/ding-dong/dingdong-django/venv34/lib/python3.4/site-packages/haystack/backends/solr_backend.py" in _process_results
  374.             app_label, model_name = raw_result[DJANGO_CT].split('.')

Exception Type: AttributeError at /api/1.0/p/products/
Exception Value: 'list' object has no attribute 'split'

๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ ์˜ˆ์™ธ์˜ ์ง€์—ญ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค:

None
raw_results 
<pysolr.Results object at 0x7fb8df0a64a8>
result_class    
<class 'haystack.models.SearchResult'>
hits    
1
unified_index   
<haystack.utils.loading.UnifiedIndex object at 0x7fb8df1b0048>
raw_result  
{'_version_': 1499926380381470720,
 'categories': ['Category object'],
 'description': ['Descripcion test'],
 'django_ct': ['products.product'],
 'django_id': [1],
 'ean': [111],
 'id': 'products.product.1',
 'name': ['Producto test 1'],
 'name_auto': ['Producto test 1'],
 'score': 0.14093116,
 'text': ['Producto test 1\n'
          '111\n'
          '\n'
          '    Categoria test\n'
          '\n'
          'Descripcion test\n'
          'None']}
distance_point  
None
stats   
{}
indexed_models  
[<class 'products.models.Product'>]
key 
'fields'
spelling_suggestion 
None
self    
<haystack.backends.solr_backend.SolrSearchBackend object at 0x7fb8df24e748>
connections 
<haystack.utils.loading.ConnectionHandler object at 0x7fb8ff447208>
results 
[]
facets  
{'dates': {}, 'fields': {}, 'queries': {}}

๋ณด์‹œ๋‹ค์‹œํ”ผ django_ct๋Š” ๋ฌธ์ž์—ด์ด ์•„๋‹ˆ๋ผ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

๋„์›€์„ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

solr highpriority

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

3-4์ผ ํ›„ ๋‚˜๋Š” ํ•ด๊ฒฐ์ฑ…์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์†”๋ฃจ์…˜ 1-: ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ

1๋‹จ๊ณ„: ์ปฌ๋ ‰์…˜ ๊ด€๋ฆฌ ์Šคํ‚ค๋งˆ ํŒŒ์ผ๋กœ ์ด๋™ํ•˜์—ฌ ํŽธ์ง‘
2๋‹จ๊ณ„: <field name="django_ct" type="text_general"/> ๋ฅผ ์ฐพ์•„์„œ <field name="django_ct" type="string"/>

  • ์šด์˜ ์ฒด์ œ ๋ฒ„์ „: Ubuntu 14.04 LTS
  • ๊ฒ€์ƒ‰ ์—”์ง„ ๋ฒ„์ „: Solr 7.2.1
  • ํŒŒ์ด์ฌ ๋ฒ„์ „: 3.4.3
  • ์žฅ๊ณ  ๋ฒ„์ „: 2.0
  • ๊ฑด์ดˆ ๋”๋ฏธ ๋ฒ„์ „: 2.8.0

์†”๋ฃจ์…˜ 2-: ํ•ต์‹ฌ ํŒŒ์ผ ํ•ดํ‚น

1๋‹จ๊ณ„: sudo vim /home/your path/site-packages/haystack/backends/solr_backend.py
2๋‹จ๊ณ„: app_label, model_name = raw_result[DJANGO_CT].split('.') ๋ฅผ ์ฐพ์•„ app_label, model_name = raw_result[DJANGO_CT][0].split('.') ๋ฐ”๊พธ๊ธฐ

๋ชจ๋“  41 ๋Œ“๊ธ€

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ๋‚ด๊ฐ€ํ•˜๊ณ ์žˆ๋Š” ์ฟผ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

results = SearchQuerySet().filter(content=Clean(value)).models(Product)

๋‚˜๋Š” solr์ด ์ƒ์„ฑ๋œ schema.xml ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Solr๋Š” ์ด์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ถˆํ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

test_shard1_replica1: org.apache.solr.common.Solr ์˜ˆ์™ธ: org.apache.solr.common.SolrException : ํ•ต์‹ฌ test_shard1_replica1์— ๋Œ€ํ•œ conf๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์—†์Œ: [schema.xml] fieldType "sint"์— ๋Œ€ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ดˆ๊ธฐํ™” ์‹คํŒจ: ํด๋ž˜์Šค 'solr ๋กœ๋“œ ์ค‘ ์˜ค๋ฅ˜ .SortableIntField'. ์Šคํ‚ค๋งˆ ํŒŒ์ผ์€ /configs/test/schema.xml์ž…๋‹ˆ๋‹ค.

์ €๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” schema.xml์ด ์˜ฌ๋ฐ”๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ–ˆ์ง€๋งŒ, ๊ทธ๊ฒƒ์„ ์–ด๋””์— ๋‘˜์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ 'server/solr/core_name_here/conf/' ์•„๋ž˜์— ๋ฐฐ์น˜ํ–ˆ๊ณ  ๋กœ๊ทธ์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ schema.xml์ด ์žˆ๊ณ  ์ด๋ฏธ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ œ๊ฑฐํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ข‹์•„, ๋‚˜๋Š” ๋ฉฐ์น  ๋™์•ˆ์ด ๋ฌธ์ œ๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ์ง€๋งŒ ๋งˆ์นจ๋‚ด ๋ฐ”๋‹ฅ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค: http://stackoverflow.com/questions/30427643/fields-in-apache-solr-response-are-multivalued-when-they-should-be-singular/30484017#30484017

Haystack์€ Solr v5.*์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์œ„์˜ ์ง€์นจ์— ๋”ฐ๋ผ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ฉด https://lucene.apache.org/solr/4_2_0/solr-core/ ์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํด๋ž˜์Šค ๋ฐ Solr์—์„œ ์™„์ „ํžˆ ์ œ๊ฑฐ๋œ ํด๋ž˜์Šค์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์•„์ง ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๋ฌธ์„œ์— ๋”ฐ๋ผ Solr v4.* ๋˜๋Š” v.3.5๋กœ ๋กค๋ฐฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์ด๋ฅผ ๋ฐ˜์˜ํ•˜์—ฌ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜๋Š” Solr์— ์ต์ˆ™ํ•˜๋‹ค๋ฉด schema.xml์„ ์ˆ˜์ •ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‚˜์ค‘์— ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ ํ‹ฐ์ผ“:
https://github.com/django-haystack/django-haystack/issues/1199

4.x๋Š” ํ™•์‹คํžˆ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ํ…Œ์ŠคํŠธ๋Š” 4.7์— ๋Œ€ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. @sampeka ํŒŒํ—ค์ณ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ๋„ #1200 ๊ฐ™์Šต๋‹ˆ๋‹ค.

#1183์— ๋Œ€ํ•œ ๋‚ด ์˜๊ฒฌ์„ ํ™•์ธํ•˜์„ธ์š”. ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๊ธฐ๋ณธ schema.xml ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ ์ ˆํ•œ Django ํ•„๋“œ์— ๋ถ™์—ฌ๋„ฃ์–ด Solr 5.1์—์„œ ์ž‘๋™ํ•˜๋„๋ก ์ธ๋ฑ์‹ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ๋ชจ๋ธ์— ๋Œ€ํ•ด ํ•„์š”์— ๋”ฐ๋ผ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜์ง€๋งŒ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์–ด๋ ค์›€์„ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” Django ์•ฑ์— ๋„ˆ๋ฌด ๋ฉ€๋ฆฌ ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ ์ ์–ด๋„ ๋‚ด ์ƒ‰์ธ์— ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด rich_content_extraction์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

@nikolaz111 ์ด ๋ฒ„๊ทธ๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋‹จ๊ณ„๋ฅผ ์•Œ์•„๋ƒˆ์Šต๋‹ˆ๋‹ค.

  • solrconfig.xml์—์„œ ๊ธฐ๋ณธ schemafactory๋ฅผ ClassicIndexSchemaFactory ํด๋ž˜์Šค๋กœ ๋ณ€๊ฒฝ
  • ํด๋ž˜์Šค initParams์˜ ๊ฒฝ์šฐ:
<initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell,/browse">
    <lst name="defaults">
      <str name="df">_text_</str>
    </lst>
  </initParams>

๋กœ ๋ณ€๊ฒฝ

<initParams path="/update/**,/query,/select,/tvrh,/elevate,/spell">
            <lst name="defaults">
            <str name="df">text</str>
            </lst>
</initParams>
  • mange.py ์žฌ๋นŒ๋“œ ์ธ๋ฑ์Šค ์‹คํ–‰
  • schema.xml์„ core์— ๋ฎ์–ด์“ฐ๋ฏ€๋กœ ManagedIndexSchemaFactory๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— solrconfig.xml์˜ ๋งŽ์€ ํด๋ž˜์Šค๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” xml์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ฃผ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.
    https://gist.github.com/DrChai/033604cd04c869f40ade

Solr 5๋ฅผ Haystack๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ค๋ฅ˜๊ฐ€ ํ•˜๋‚˜์”ฉ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ text_general ํ•„๋“œ ์œ ํ˜•์— ๋Œ€ํ•ด Error instantiating class: 'org.apache.lucene.analysis.core.StopFilterFactory' ์— ๊ณ ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ž‘๋™ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ€์žฅ ํฐ ๊ถŒ์žฅ ์‚ฌํ•ญ์€ ๊ธฐ๋ณธ Solr schema.xml์„ ์‚ฌ์šฉํ•˜๊ณ  ํ•„์š”ํ•œ Django ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. id, django_ct, *_exact(๋ฐฉ๊ธˆ ๋™์  ํ•„๋“œ๋กœ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค) ๋ฐ ๊ธฐํƒ€ ๋ช‡ ๊ฐ€์ง€๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๋Š” ๊ฒƒ๋ณด๋‹ค ์‹œ๊ฐ„์„ ๋งŽ์ด ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ๋ผ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ํฌ๊ธฐํ•˜๊ณ  Solr์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” "๋™์ " ์Šคํ‚ค๋งˆ๋ฅผ ๊ณ ์ˆ˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค https://github.com/nazariyg/Solr-5-for-django-haystack

๊ธ์ •์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด๋ณด๊ณ  ๋‹ค์‹œ ๋ณด๊ณ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@nazariyg ์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๋‘ํ†ต.

@nazariyg ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์— ์–ด๋–ค Haystack ๋ฐ Django ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
์ €๋Š” Django 1.9.4๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๊ณ  Win์—์„œ Solr 5.5๋ฅผ ์‹œ๋„ํ•˜๋Š” Haystack 2.5๋ฅผ ๋‹ค์šด๋กœ๋“œํ–ˆ์Šต๋‹ˆ๋‹ค.
ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์—๋Š” Solr์—์„œ ๋‹จ์ผ ํžˆํŠธ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋ฌธ์ œ์— ์ง๋ฉดํ•ด ์žˆ์Šต๋‹ˆ๋‹ค.

_'list' ๊ฐœ์ฒด์— 'split' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ด ์‹œ์ ์—์„œ solr_backend.py๊ฐ€ ๋˜์กŒ์Šต๋‹ˆ๋‹ค.

  for raw_result in raw_results.docs:
            app_label, model_name = raw_result[DJANGO_CT].split('.') 

SOLR6๊ณผ ํ†ตํ•ฉํ•  ๋•Œ ์ถ”๊ฐ€ ๊ตฌ์„ฑ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋งํฌ์—์„œ ์ˆ˜ํ–‰ํ•œ ๋‹จ๊ณ„๋ฅผ ๋ฌธ์„œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

https://github.com/dekanayake/haystack_solr6

๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ์Šต๋‹ˆ๊นŒ? ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค.
๋‚˜๋Š” ๋ชจ๋“  ๊ฒƒ์— ์ตœ์‹  ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.

@dekanayake ํ™๋ณด ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด Haystack์€ Solr 6๊ณผ ํ˜ธํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@cauanicastro ์˜ค๋žœ๋งŒ์ž…๋‹ˆ๋‹ค. #1504 ์Šคํ‚ค๋งˆ ์ƒ์„ฑ์„ ์œ„ํ•œ ์ผ๋ถ€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์ง€๋งŒ ๊ฝค ์˜ค๋žซ๋™์•ˆ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ์ด ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ์‹ค๋ง

@wagaman ์•„์ง๋„ ์ด ๋ฒ„๊ทธ๊ฐ€ ์กด์žฌํ•˜๋‚˜์š”?

@wagaman ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. slor 6์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์›์‹œ HTML์„ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ ํ–‰์ด ์ƒ๋‹นํžˆ ํฝ๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋ฅผ ์žฌ์ƒ์„ฑํ•˜๋ฉด ๋‚ด HTML ์…€์ธ " ์ฝ˜ํ…์ธ  "๊ฐ€ ๋„ˆ๋ฌด ํฝ๋‹ˆ๋‹ค. ์˜จ๋ผ์ธ ์ž์Šต์„œ ๋ฅผ ๋”ฐ๋ผ ๋ฌธ์ž์—ด์—์„œ text_general๋กœ ์œ ํ˜•์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

pysolr.SolrError: Solr responded with an error (HTTP 400): [Reason: Exception writing document id piaoyouquan.piaoyou.1003 to the index; possible analysis error: Document contains at least one immense term in field="content" (whose UTF8 encoding is longer than the max length 32766), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: '[60, 100, 105, 118, 32, 99, 108, 97, 115, 115, 61, 34, 114, 105, 99, 104, 95, 109, 101, 100, 105, 97, 95, 97, 114, 101, 97, 95, 112, 114]...', original message: bytes can be at most 32766 in length; got 86946. Perhaps the document has an indexed string field (solr.StrField) which is too large]

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฒ€์ƒ‰์„ ์‹œ๋„ํ•  ๋•Œ "'๋ชฉ๋ก' ๊ฐœ์ฒด์— '๋ถ„ํ• ' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค"๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์— ์ฝ”๋“œ๋ฅผ ๊ฒŒ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

/search/์˜ AttributeError
'list' ๊ฐœ์ฒด์— 'split' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
์š”์ฒญ ๋ฐฉ๋ฒ•: GET
์š”์ฒญ URL: http://127.0.0.1 :8000/search/?q=w
์žฅ๊ณ  ๋ฒ„์ „: 1.10
์˜ˆ์™ธ ์œ ํ˜•: AttributeError
์˜ˆ์™ธ ๊ฐ’:
'list' ๊ฐœ์ฒด์— 'split' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
์˜ˆ์™ธ ์œ„์น˜: /Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py์˜ _process_results, 406ํ–‰
ํŒŒ์ด์ฌ ์‹คํ–‰ ํŒŒ์ผ: /Users/ja/3.5/bin/python
ํŒŒ์ด์ฌ ๋ฒ„์ „: 3.5.1
ํŒŒ์ด์ฌ ๊ฒฝ๋กœ:
['/Users/ja/Dropbox/Programming/Django/piaoyou',
'/์‚ฌ์šฉ์ž/ja/3.5/lib/python35.zip',
'/์‚ฌ์šฉ์ž/ja/3.5/lib/python3.5',
'/์‚ฌ์šฉ์ž/ja/3.5/lib/python3.5/plat-darwin',
'/์‚ฌ์šฉ์ž/ja/3.5/lib/python3.5/lib-dynload',
'/๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ/Frameworks/Python.framework/Versions/3.5/lib/python3.5',
'/๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin',
'/์‚ฌ์šฉ์ž/ja/3.5/lib/python3.5/์‚ฌ์ดํŠธ ํŒจํ‚ค์ง€',
'/๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages']
์„œ๋ฒ„ ์‹œ๊ฐ„: 2017๋…„ 6์›” 26์ผ ์›”์š”์ผ 05:01:18 +0000

ํ™˜๊ฒฝ:

์š”์ฒญ ๋ฐฉ๋ฒ•: GET
์š”์ฒญ URL: http://127.0.0.1 :8000/search/?q=w

์žฅ๊ณ  ๋ฒ„์ „: 1.10
ํŒŒ์ด์ฌ ๋ฒ„์ „: 3.5.1
์„ค์น˜๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜:
['๋‹ฌ',
'๋‹ฌ_์„ ํƒ2',
'๋งž์ถค_ํ…œํ”Œ๋ฆฟ',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'ํ‘œ์œ ๊ถŒ',
'rest_framework',
'ํŽ˜์ด์ง€๋‹ค์šด',
'๋ฐ”์‚ญํ•œ ํ˜•ํƒœ',
'ํƒ€๊นƒ',
'ํƒœ๊ทธ๊นƒ_ํ…œํ”Œ๋ฆฟํƒœ๊ทธ2',
'์ปค๋‹ค๋ž€ ๊ฑด์ดˆ ๋”๋ฏธ',
'ํ—‰',
'๋‹ค์Œ_์ด์ „',
'django_extensions']
์„ค์น˜๋œ ๋ฏธ๋“ค์›จ์–ด:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']

์—ญ ์ถ”์ :

ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/paginator.py" ๊ฐœ์ˆ˜

  1. ๋ฐ˜ํ™˜ self.object_list.count()

ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/query.py" ๊ฐœ์ˆ˜

  1. ๋ฐ˜ํ™˜ len(์ž์ฒด)

__len__์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/query.py" ํŒŒ์ผ

  1. self._result_count = self.query.get_count()

get_count์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/__init__.py" ํŒŒ์ผ

  1. self.run()

์‹คํ–‰ ์ค‘์ธ ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py"

  1. ๊ฒฐ๊ณผ = self.backend.search(final_query, **search_kwargs)

๋ž˜ํผ์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/__init__.py" ํŒŒ์ผ

  1. return func(obj, query_string, args, * kwargs)

๊ฒ€์ƒ‰์—์„œ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py" ํŒŒ์ผ

  1. distance_point=kwargs.get('distance_point'))

_process_results์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py" ํŒŒ์ผ

  1. app_label, model_name = raw_result[DJANGO_CT].split('.')

์œ„์˜ ์˜ˆ์™ธ('list' ๊ฐœ์ฒด์—๋Š” 'split' ์†์„ฑ์ด ์—†์Œ)๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/handlers/exception.py"

  1. ์‘๋‹ต = get_response(์š”์ฒญ)

_get_response์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" ํŒŒ์ผ

  1. ์‘๋‹ต = self.process_exception_by_middleware(e, ์š”์ฒญ)

_get_response์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" ํŒŒ์ผ

  1. ์‘๋‹ต = wrap_callback(์š”์ฒญ, callback_args, * callback_kwargs)

๋ณด๊ธฐ์—์„œ "/Users/ja/3.5/lib/python3.5/site-packages/django/views/generic/base.py" ํŒŒ์ผ

  1. ๋ฐ˜ํ™˜ self.dispatch(์š”์ฒญ, ์ธ์ˆ˜, * kwargs)

๋””์ŠคํŒจ์น˜์—์„œ "/Users/ja/3.5/lib/python3.5/site-packages/django/views/generic/base.py" ํŒŒ์ผ

  1. ๋ฐ˜ํ™˜ ํ•ธ๋“ค๋Ÿฌ(์š”์ฒญ, ์ธ์ˆ˜, * kwargs)

ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/generic_views.py" ๊ฐ€์ ธ์˜ค๊ธฐ

  1. self.form_valid(์–‘์‹) ๋ฐ˜ํ™˜

form_valid์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/generic_views.py" ํŒŒ์ผ

  1. 'object_list': self.queryset

get_context_data์˜ "/Users/ja/Dropbox/Programming/Django/piaoyou/piaoyouquan/view.py" ํŒŒ์ผ

  1. ์ปจํ…์ŠคํŠธ = super(BillSearchView, ์ž์ฒด).get_context_data( ์ธ์ˆ˜, * kwargs)

get_context_data์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/views/generic/list.py" ํŒŒ์ผ

  1. ํŽ˜์ด์ง€ ๋งค๊น€, ํŽ˜์ด์ง€, ์ฟผ๋ฆฌ ์„ธํŠธ, is_paginated = self.paginate_queryset(queryset, page_size)

paginate_queryset์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/views/generic/list.py" ํŒŒ์ผ

  1. ํŽ˜์ด์ง€ = paginator.page(page_number)

ํŽ˜์ด์ง€์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/paginator.py" ํŒŒ์ผ

  1. ์ˆซ์ž = self.validate_number(์ˆซ์ž)

validate_number์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/paginator.py" ํŒŒ์ผ

  1. ์ˆซ์ž > self.num_pages์ธ ๊ฒฝ์šฐ:

__get__์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/utils/functional.py" ํŒŒ์ผ

  1. res = instance.__dict__[self.name] = self.func(instance)

num_pages์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/paginator.py" ํŒŒ์ผ

  1. self.count == 0์ด๊ณ  self.allow_empty_first_page๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ:

__get__์˜ "/Users/ja/3.5/lib/python3.5/site-packages/django/utils/functional.py" ํŒŒ์ผ

  1. res = instance.__dict__[self.name] = self.func(instance)

ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/django/core/paginator.py" ๊ฐœ์ˆ˜

  1. ๋ฐ˜ํ™˜ len(self.object_list)

__len__์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/query.py" ํŒŒ์ผ

  1. self._result_count = self.query.get_count()

get_count์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/__init__.py" ํŒŒ์ผ

  1. self.run()

์‹คํ–‰ ์ค‘์ธ ํŒŒ์ผ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py"

  1. ๊ฒฐ๊ณผ = self.backend.search(final_query, **search_kwargs)

๋ž˜ํผ์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/__init__.py" ํŒŒ์ผ

  1. return func(obj, query_string, args, * kwargs)

๊ฒ€์ƒ‰์—์„œ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py" ํŒŒ์ผ

  1. distance_point=kwargs.get('distance_point'))

_process_results์˜ "/Users/ja/3.5/lib/python3.5/site-packages/haystack/backends/solr_backend.py" ํŒŒ์ผ

  1. app_label, model_name = raw_result[DJANGO_CT].split('.')

์˜ˆ์™ธ ์œ ํ˜•: /search/์˜ AttributeError
์˜ˆ์™ธ ๊ฐ’: 'list' ๊ฐœ์ฒด์— 'split' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ €๋Š” Haystack๊ณผ ํ•จ๊ป˜ Whoosh๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ Django์˜ ๋™์ผํ•œ ์ฝ”๋“œ์—์„œ ์ž˜ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

Appium-Python-Client==0.24
์•„๋ฆ„๋‹ค์šด ์ˆ˜ํ”„4==4.4.1
์‚ฌ์ดํด๋Ÿฌ==0.10.0
์žฅ๊ณ ==1.10
django-autocomplete-light==3.2.7
django-classy-tags==0.8.0
django-crispy-forms==1.6.1
์žฅ๊ณ  ํ™•์žฅ ==1.7.9
์žฅ๊ณ  ํ•„ํ„ฐ==1.0.4
django-haystack==2.6.1
django-next-prev==1.0.1
์žฅ๊ณ  ํŽ˜์ด์ง€๋‹ค์šด==0.1.3
django-taggit==0.22.1
django-taggit-templatetags2==1.6.1
์žฅ๊ณ -uuslug==1.1.8
์žฅ๊ณ ๋ ˆ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ==3.6.3
dnspython==1.15.0
EasyProcess==0.2.3
ez-์„ค์ •==0.9
๊ฐ€์งœ ์‚ฌ์šฉ์ž ์—์ด์ „ํŠธ == 0.1.7
gevent==1.2.2
๊ทธ๋ฆฐ๋ ›==0.4.12
๊ฑด์ดˆ๋”๋ฏธ==0.36
์ง€๋ฐ”==0.38
lxml==3.6.0
๋งˆํฌ๋‹ค์šด==2.6.8
matplotlib==2.0.0
numpy==1.11.0
olefile==0.44
๋ฒ ๊ฐœ==4.1.0
ํŒŒ์ด๋‹ทํ”Œ๋Ÿฌ์Šค==2.0.2
ํŒŒ์ดํŒŒ์‹ฑ==2.1.10
ํŒŒ์ดํ…Œ์„œ๋ž™ํŠธ==0.1.7
ํŒŒ์ด์ฌ-dateutil==2.6.0
python-slugify==1.2.4
ํ”ผ์ธ ==2016.10
ํŒŒ์ด๊ฐ€์ƒ๋””์Šคํ”Œ๋ ˆ์ด==0.2.1
์ •๊ทœ์‹==2016.4.25
์š”์ฒญ==2.9.1
์‚ฌ์ดํ‚ท๋Ÿฐ==0.18.1
์‚ฌ์ดํ”ผ==0.19.0
์…€๋ ˆ๋Š„==3.4.3
6==1.10.0
sklearn==0.0
ํ…Œ์„œ๋ž™ํŠธ==0.1.3
tqdm==4.14.0
์œ ๋‹ˆ์ฝ”๋“œ==0.4.20
์—…๋ฐ์ดํŠธ==0.4.4
Werkzeug==0.12.2
ํ—‰==2.7.4
winappdbg==1.5
xvfbwrapper==0.2.9

3-4์ผ ํ›„ ๋‚˜๋Š” ํ•ด๊ฒฐ์ฑ…์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์†”๋ฃจ์…˜ 1-: ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ

1๋‹จ๊ณ„: ์ปฌ๋ ‰์…˜ ๊ด€๋ฆฌ ์Šคํ‚ค๋งˆ ํŒŒ์ผ๋กœ ์ด๋™ํ•˜์—ฌ ํŽธ์ง‘
2๋‹จ๊ณ„: <field name="django_ct" type="text_general"/> ๋ฅผ ์ฐพ์•„์„œ <field name="django_ct" type="string"/>

  • ์šด์˜ ์ฒด์ œ ๋ฒ„์ „: Ubuntu 14.04 LTS
  • ๊ฒ€์ƒ‰ ์—”์ง„ ๋ฒ„์ „: Solr 7.2.1
  • ํŒŒ์ด์ฌ ๋ฒ„์ „: 3.4.3
  • ์žฅ๊ณ  ๋ฒ„์ „: 2.0
  • ๊ฑด์ดˆ ๋”๋ฏธ ๋ฒ„์ „: 2.8.0

์†”๋ฃจ์…˜ 2-: ํ•ต์‹ฌ ํŒŒ์ผ ํ•ดํ‚น

1๋‹จ๊ณ„: sudo vim /home/your path/site-packages/haystack/backends/solr_backend.py
2๋‹จ๊ณ„: app_label, model_name = raw_result[DJANGO_CT].split('.') ๋ฅผ ์ฐพ์•„ app_label, model_name = raw_result[DJANGO_CT][0].split('.') ๋ฐ”๊พธ๊ธฐ

@acdha ์ด๊ฒŒ ๋ญ์•ผ?

์ด ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ๊ธฐ๋ณธ๊ฐ’์—์„œ ์Šคํ‚ค๋งˆ ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? Haystack์€ https://github.com/django-haystack/django-haystack/blob/9eb42dac5cd918c991ac7c939d6de81a02a1aba1/haystack/templates/search_configuration/schema.xml์— ๋”ฐ๋ผ string ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  text_general ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

@krmritunjay11 ํ…Œ์ŠคํŠธ

๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์„œ @krmritunjay11 ์ด ์œ„์— ๊ฒŒ์‹œํ•œ ๋‘ ๋ฒˆ์งธ ์†”๋ฃจ์…˜์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ์ฝ”๋“œ์™€ ํ™˜๊ฒฝ์ด Whoosh์™€ ํ•จ๊ป˜ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ํ™˜๊ฒฝ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
requirements.txt , ๊ทธ๋ฆฌ๊ณ  Solr 7.3.1์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(ํ•˜์ง€๋งŒ Solr 6.X๋ฅผ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค)

๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

File "<yourpath>/site-packages/django/db/models/fields/__init__.py", line 947, in get_prep_value
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

์œ„ ํŒŒ์ผ์˜ 947ํ–‰์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

 return int(value)

์—๊ฒŒ

 if isinstance(value, list):
     return int(value[0])
 return int(value)

์ด๋กœ ์ธํ•ด ๋˜ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

File "<your path>/site-packages/haystack/query.py", line 181, in post_process_results
    result.pk = result_klass(result.pk)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

181๋ฒˆ ์ค„์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ˆ˜์ •ํ•œ ๊ฒƒ

 result.pk = result_klass(result.pk)

์—๊ฒŒ

 if isinstance(result.pk, list):
    result.pk = result_klass(result.pk[0])
 else:
   result.pk = result_klass(result.pk)

์ด์ œ ๊ฒ€์ƒ‰์ด ์ž‘๋™ํ•˜์ง€๋งŒ ๋‚ด ์†”๋ฃจ์…˜์ด ํ•ดํ‚น๋˜๊ณ  ๊ฐ•๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์™œ ์ด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์ด ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

django์˜ ํ•ต์‹ฌ ํŒŒ์ผ์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

์—/site-packages/haystack/query.py, 181ํ–‰์„ ๋‹ค์Œ์—์„œ ๋ณ€๊ฒฝ:

result.pk = result_klass(result.pk)

NS:

result.pk = result_klass(result.pk[0])

205ํ–‰ ์•ž์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

pks = [pk[0] for pk in pks]

๋”ฐ๋ผ์„œ try ๋ธ”๋ก์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋๋‚ฉ๋‹ˆ๋‹ค.

207         try:
208             ui = connections[self.query._using].get_unified_index()
209             index = ui.get_index(model)
210             objects = index.read_queryset(using=self.query._using)
211             pks = [pk[0] for pk in pks]
212             return objects.in_bulk(pks)

django 1.11, haystack 2.7.0 ๋ฐ solr 5.5.5๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”.

๋‚˜๋Š” ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ณ  ๋‹ค๋ฅธ ํ•ด์„ค์ž์˜ ์†”๋ฃจ์…˜์„ ๊ฒฐํ•ฉํ•˜์—ฌ ์ž‘๋™ํ•˜๋Š” ์†”๋ฃจ์…˜์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ์ข‹์€ ์ ์€ SolrEngine์„ ์žฌ์ •์˜ํ•˜๊ณ  ๊ฑด์ดˆ ๋”๋ฏธ์—์„œ ์ˆ˜์ •๋  ๋•Œ๊นŒ์ง€ ๊ณ ์ • ๋ฒ„์ „์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ €๋Š” haystack 2.8.1๊ณผ solr 8.5.2๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

haystack/backends/solr_backend.py ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜์—ฌ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

  • ์ฐพ๊ธฐ ๋ฐ ๋ฐ”๊พธ๊ธฐ
    python app_label, model_name = raw_result[DJANGO_CT].split('.')
    ์—๊ฒŒ
    python app_label, model_name = raw_result[DJANGO_CT][0].split('.')
  • ์ฐพ๊ธฐ ๋ฐ ๋ฐ”๊พธ๊ธฐ
    python result = result_class(app_label, model_name, raw_result[DJANGO_ID], raw_result['score'], **additional_fields)
    ์—๊ฒŒ
    python result = result_class(app_label, model_name, raw_result[DJANGO_ID][0], raw_result['score'], **additional_fields)
  • ์ฐพ๊ธฐ ๋ฐ ๋ฐ”๊พธ๊ธฐ
    python for key, value in raw_result.items(): value = value[0]
    ์—๊ฒŒ
    python for key, value in raw_result.items(): if isinstance(value, list): value = value[0]

๋ชจ๋“  ํ™๋ณด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ํ™๋ณด๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ํ•˜์ง€๋งŒ ์™„์ „ํžˆ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜์„ ์ œ์•ˆํ•  ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์œ ๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ Solr ์—”์ง„์˜ ๋‚ฎ์€ ๋ฒ„์ „์—์„œ๋Š” ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ PR์„ ๋งŒ๋“ค ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

django-haystack 3.0 ๋ฐ Solr 7.7.3์„ ์‚ฌ์šฉํ•˜์—ฌ ์žฌํ˜„ ๊ฐ€๋Šฅ

@jcrbsa ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์„ ์žฌํ˜„ํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.

@acdha , ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค.

์–‘์‹๋ณ„ ์ฟผ๋ฆฌ ํ›„ solr_backend.py์— ๋‹ค์Œ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
C:\Python37\lib\site-packages\haystack\backends\solr_backend.py, 525ํ–‰, _process_results

solr_backend.py๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์–‘์‹๋ณ„๋กœ ์ƒˆ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ ํ›„ ๋‹ค์Œ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
C:\Python37\lib\site-packages\django\db\models\fields__init__.py, ํ–‰ 1778, get_prep_value

์˜ˆ์ƒ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋Š” ํ‘œ์ค€ Solr ์Šคํ‚ค๋งˆ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์žฌ์ƒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰