-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recherche via Elasticsearch #4096
Changes from 7 commits
afbd1c0
221b5ff
cb01421
e61ffc1
280a4fe
682010f
c68752b
f72b30f
eb8aaed
fcc1cfa
a6f341c
987a7cf
f7439ae
d7addd3
ddd2e72
0e41258
2a8b603
40bee12
a278ef5
1c73993
553fee8
282ff34
1f32be3
c665752
437f913
8a13142
dc96397
0240817
f166f51
bd062bf
2b99fdc
1d7c0a6
2b92ec7
4a25510
0b3f61f
437c961
669954c
32ba8af
d6f4cbe
6104d9f
83d7224
83e662c
14b20a0
5a28679
48af348
3544f3e
22a9b11
4142a93
28215cb
2c22184
13ef3a1
2c14aac
f0ce199
bf36ebb
869df81
944d5a6
c70d210
98f786a
d662c7a
28c3677
79cc588
7feac1b
c1f4745
7adb8fb
422dbc3
964acf9
adebf61
ba6867f
429c8da
92f38ab
f7cab5b
d04b82c
eb0dd5a
aa05f19
bda0ea0
4ff0a26
da373f6
ea150e8
8f6d2c0
1eacfcd
38ebf2d
9671892
76e8748
3f3f28a
9f6192d
01c5890
a5b632e
ae7dec1
e4eeb0e
62e2f9c
e3754a4
0b969e1
1e3f160
38a69d9
fa9f102
55c66d7
7db240f
de57f24
3add954
4b4c6fb
8f02288
df7cd38
451280c
e9fcf7d
1b69595
e804a2f
e415c99
f4b6221
0fda5a8
c03dca7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# -*- coding: utf-8 -*- | ||
from __future__ import unicode_literals | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tu sais que je t'aime toi. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. <3 |
||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('forum', '0010_auto_20161112_1823'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='post', | ||
name='es_already_indexed', | ||
field=models.BooleanField(default=False, db_index=True, verbose_name=b'D\xc3\xa9j\xc3\xa0 index\xc3\xa9 par ES'), | ||
), | ||
migrations.AddField( | ||
model_name='post', | ||
name='es_flagged', | ||
field=models.BooleanField(default=True, db_index=True, verbose_name=b'Doit \xc3\xaatre (r\xc3\xa9)index\xc3\xa9 par ES'), | ||
), | ||
migrations.AddField( | ||
model_name='topic', | ||
name='es_already_indexed', | ||
field=models.BooleanField(default=False, db_index=True, verbose_name=b'D\xc3\xa9j\xc3\xa0 index\xc3\xa9 par ES'), | ||
), | ||
migrations.AddField( | ||
model_name='topic', | ||
name='es_flagged', | ||
field=models.BooleanField(default=True, db_index=True, verbose_name=b'Doit \xc3\xaatre (r\xc3\xa9)index\xc3\xa9 par ES'), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,9 +10,12 @@ | |
from django.core.urlresolvers import reverse | ||
from django.db import models | ||
|
||
from elasticsearch_dsl.field import Text, Keyword | ||
|
||
from zds.forum.managers import TopicManager, ForumManager, PostManager, TopicReadManager | ||
from zds.notification import signals | ||
from zds.settings import ZDS_APP | ||
from zds.search2.models import AbstractESDjangoIndexable | ||
from zds.utils import get_current_user | ||
from zds.utils import slugify | ||
from zds.utils.models import Comment, Tag | ||
|
@@ -157,7 +160,7 @@ def can_read(self, user): | |
|
||
|
||
@python_2_unicode_compatible | ||
class Topic(models.Model): | ||
class Topic(AbstractESDjangoIndexable): | ||
""" | ||
A Topic is a thread of posts. | ||
A topic has several states, witch are all independent: | ||
|
@@ -382,9 +385,39 @@ def old_post_warning(self): | |
|
||
return False | ||
|
||
@classmethod | ||
def get_es_mapping(cls): | ||
es_mapping = super(Topic, cls).get_es_mapping() | ||
|
||
es_mapping.field('title', Text()) | ||
es_mapping.field('subtitle', Text()) | ||
es_mapping.field('get_absolute_url', Text(index='not_analyzed')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(Je mets qu'un commentaire, mais faut changer les 18 occurrences de |
||
es_mapping.field('tags', Keyword()) | ||
|
||
return es_mapping | ||
|
||
@classmethod | ||
def get_es_django_indexable(cls, force_reindexing=False): | ||
"""Overridden to remove hidden forums (and prefetch tags) | ||
""" | ||
|
||
query = super(Topic, cls).get_es_django_indexable(force_reindexing) | ||
return query.prefetch_related('tags').filter(forum__group__isnull=True) | ||
|
||
def get_es_document_source(self, excluded_fields=None): | ||
"""Overridden to handle the case of tags (M2M field) | ||
""" | ||
|
||
excluded_fields = excluded_fields or [] | ||
excluded_fields.extend(['tags']) | ||
|
||
data = super(Topic, self).get_es_document_source(excluded_fields=excluded_fields) | ||
data['tags'] = [tag.title for tag in self.tags.all()] | ||
return data | ||
|
||
|
||
@python_2_unicode_compatible | ||
class Post(Comment): | ||
class Post(Comment, AbstractESDjangoIndexable): | ||
""" | ||
A forum post written by an user. | ||
A post can be marked as useful: topic's author (or admin) can declare any topic as "useful", and this post is | ||
|
@@ -413,6 +446,23 @@ def get_absolute_url(self): | |
def get_notification_title(self): | ||
return self.topic.title | ||
|
||
@classmethod | ||
def get_es_mapping(cls): | ||
m = super(Post, cls).get_es_mapping() | ||
|
||
m.field('text', Text()) | ||
m.field('get_absolute_url', Text(index='not_analyzed')) | ||
|
||
return m | ||
|
||
@classmethod | ||
def get_es_django_indexable(cls, force_reindexing=False): | ||
"""Overridden to remove invisible post | ||
""" | ||
|
||
q = super(Post, cls).get_es_django_indexable(force_reindexing) | ||
return q.filter(is_visible=True) | ||
|
||
|
||
@python_2_unicode_compatible | ||
class TopicRead(models.Model): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# coding: utf-8 | ||
from django.conf import settings | ||
from elasticsearch_dsl.connections import connections | ||
|
||
DEFAULT_ES_CONNECTIONS = { | ||
'default': { | ||
'hosts': ['localhost:9200'], | ||
} | ||
} | ||
|
||
INDEX_NAME = getattr(settings, 'ES_INDEX_NAME', 'elastic') | ||
CONNECTIONS = getattr(settings, 'ES_CONNECTIONS', DEFAULT_ES_CONNECTIONS) | ||
|
||
|
||
def setup_es_connections(): | ||
"""Create connection(s) to Elasticsearch from parameters defined in the settings. | ||
|
||
CONNECTIONS is a dict, where the keys are connection aliases and the values are parameters to the | ||
``elasticsearch_dsl.connections.connection.create_connection()`` function (which are directly passed to an | ||
Elasticsearch object, see http://elasticsearch-py.readthedocs.io/en/master/api.html#elasticsearch for the options). | ||
|
||
""" | ||
|
||
for alias, params in CONNECTIONS.items(): | ||
connections.create_connection(alias, **params) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# coding: utf-8 | ||
|
||
from django.core.management.base import BaseCommand, CommandError | ||
|
||
from zds.search2 import INDEX_NAME, setup_es_connections | ||
from zds.search2.models import ESIndexManager, get_django_indexable_objects | ||
from zds.tutorialv2.models.models_database import FakeChapter | ||
|
||
|
||
class Command(BaseCommand): | ||
help = 'Manage data from/to ES' | ||
|
||
indexer = None | ||
models = get_django_indexable_objects() | ||
|
||
def __init__(self, *args, **kwargs): | ||
super(Command, self).__init__(*args, **kwargs) | ||
|
||
self.models.insert(0, FakeChapter) # FakeChapter needs to be first | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument('action', type=str) | ||
|
||
def handle(self, *args, **options): | ||
setup_es_connections() | ||
self.indexer = ESIndexManager(INDEX_NAME) | ||
|
||
if options['action'] == 'setup': | ||
self.setup_es() | ||
elif options['action'] == 'index-all': | ||
self.index_documents(force_reindexing=True) | ||
elif options['action'] == 'index-flagged': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Du coup j'ai pas compris cette notion de "flagged". Peux-tu l'expliquer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ben en gros, ça évite de réindexer ce qui est déjà indexé et qui à priori n'a pas changé. Lorsqu'on récupère les objets à indexer, on ne récupère que ceux qui sont à There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merci 👍 |
||
self.index_documents(force_reindexing=False) | ||
else: | ||
raise CommandError('unknown action {}'.format(options['action'])) | ||
|
||
def setup_es(self): | ||
|
||
self.indexer.reset_es_index() | ||
self.indexer.setup_es_mappings(self.models) | ||
|
||
def index_documents(self, force_reindexing=False): | ||
|
||
if force_reindexing: | ||
self.setup_es() # remove all previous data | ||
|
||
for model in self.models: | ||
self.indexer.es_bulk_indexing_of_model(model, force_reindexing=force_reindexing) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bon, ça, c'est moche, faut que je me fixe une version et que je m'y tienne.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tu es en dev, tu mettras la dernière version en date lorsque le WIP sera terminée. (pip freeze tout ça)