在Django中管理ElasticSearch索引
django-elastic-migrations的Python项目详细描述
概述
Elastic为我们提供了基本的Python工具来处理其搜索索引:
- elasticsearch py ,一个到elasticsearch的rest api的python接口
- elasticsearch dsl py ,一种声明elasticsearch模式的django式方法, 建立在elasticsearch py上
Django Elastic Migrations将这些工具调整为Django应用程序,该应用程序还:
- 为 list ing索引提供django管理命令,并执行 创建 , 更新 , 激活 和 删除 对它们的操作
- 实现由python支持的并发批量索引 多处理
- 为ElasticSearch提供Django测试挂钩
- 记录更改ElasticSearch索引的所有操作的历史记录
- 支持AWS ElasticSearch 6.0、6.1(6.2待定;请参阅 \3支持ElasticSearch DSL 6.2 )
- 允许两个或多个服务器共享同一个ElasticSearch群集
型号
Django Elastic Migrations提供三种Django型号: 索引 , 索引版本 ,以及索引:
- 索引 —对ElasticSearch索引的逻辑引用。 每个索引都指向多个索引版本,每个索引版本都包含 在特定时间的 索引 模式的快照。每个索引都有一个 活动的 索引版本 所有操作都指向该版本。
- 索引版本 -特定位置的elasticsearch 索引 架构的快照 时间点。elasticsearch索引名是 索引的名称 加上 索引版本 模型的主键id,例如电影-1的主键id。当架构是 更改后,将添加一个新的索引版本,名称为movies-2等。
- 索引 -影响 索引 的更改记录,例如更新 索引或更改哪个索引版本在索引中处于活动状态。
管理命令
使用 /manage.py es --help来查看所有这些命令的列表。
只读命令
-
/manage.py es\u列表
-
帮助:对于每个索引,列出激活状态和文档
对每个索引版本进行计数
-
用法:
/manage.py es_list
操作命令
这些管理命令在数据库中添加操作记录, 因此每个 索引的历史记录已录制。
- /manage.py es_create -创建新索引。
- /manage.py es_activate - 激活一个新的 索引版本。全部的 更新并读取索引,然后转到该版本。
- /manage.py es_update -更新索引中的文档。
- /manage.py es_clear -从索引中删除文档。
- /manage.py es_drop -删除索引。
- /manage.py es_dangerous_reset -删除ElasticSearch并重置 django弹性迁移模型。
对于每种情况,使用 --help 查看详细信息。
用法
安装
pip install
django elastic migrations
;请参见pypi上的
django elastic migrations
。
在
requirements.txt中引用此包
确保可访问有效的elasticsearch dsl py版本,并进行配置
Django设置中配置的ElasticSearch Singleton客户端的路径:
django_elastic_migrations_es_client="tests.es_config.es_client"
。
在您的应用程序中应该只有一个实例化的es_客户端。
将django弹性迁移添加到django中已安装的应用程序中
设置文件
将以下信息添加到django设置文件:
DJANGO_ELASTIC_MIGRATIONS_ES_CLIENT = "path.to.your.singleton.ES_CLIENT"
# optional, any unique number for your releases to associate with indexes
DJANGO_ELASTIC_MIGRATIONS_GET_CODEBASE_ID = subprocess.check_output(['git', 'describe', "--tags"]).strip()
# optional, can be used to have multiple servers share the same
# elasticsearch instance without conflicting
DJANGO_ELASTIC_MIGRATIONS_ENVIRONMENT_PREFIX = "qa1_"
通过运行
/manage.py migrate创建
django_elastic_migrations
表
创建一个
demindex
:
from django_elastic_migrations.indexes import DEMIndex, DEMDocType
from .models import Movie
from elasticsearch_dsl import Text
MoviesIndex = DEMIndex('movies')
@MoviesIndex.doc_type
class MovieSearchDoc(DEMDocType):
text = TEXT_COMPLEX_ENGLISH_NGRAM_METAPHONE
@classmethod
def get_queryset(self, last_updated_datetime=None):
"""
return a queryset or a sliceable list of items to pass to
get_reindex_iterator
"""
qs = Movie.objects.all()
if last_updated_datetime:
qs.filter(last_modified__gt=last_updated_datetime)
return qs
@classmethod
def get_reindex_iterator(self, queryset):
return [
MovieSearchDoc(
text="a little sample text").to_dict(
include_meta=True) for g in queryset]
将新索引添加到settings/common.py中的django_elastic_migrations_index
运行
/manage.py es_list以查看可用的索引:
./manage.py es_list
Available Index Definitions:
+----------------------+-------------------------------------+---------+--------+-------+-----------+
| Index Base Name | Index Version Name | Created | Active | Docs | Tag |
+======================+=====================================+=========+========+=======+===========+
| movies | | 0 | 0 | 0 | Current |
| | | | | | (not |
| | | | | | created) |
+----------------------+-------------------------------------+---------+--------+-------+-----------+
Reminder: an index version name looks like 'my_index-4', and its base index name
looks like 'my_index'. Most Django Elastic Migrations management commands
take the base name (in which case the activated version is used)
or the specific index version name.
使用
/manage.py es_create movies在elasticsearch中创建
电影
索引:
$> ./manage.py es_create movies
The doc type for index 'movies' changed; created a new index version
'movies-1' in elasticsearch.
$> ./manage.py es_list
Available Index Definitions:
+----------------------+-------------------------------------+---------+--------+-------+-----------+
| Index Base Name | Index Version Name | Created | Active | Docs | Tag |
+======================+=====================================+=========+========+=======+===========+
| movies | movies-1 | 1 | 0 | 0 | 07.11.005 |
| | | | | | -93-gd101 |
| | | | | | a1f |
+----------------------+-------------------------------------+---------+--------+-------+-----------+
Reminder: an index version name looks like 'my_index-4', and its base index name
looks like 'my_index'. Most Django Elastic Migrations management commands
take the base name (in which case the activated version is used)
or the specific index version name.
激活
movies-1索引版本,以便所有更新和读取都转到它。
./manage.py es_activate movies
For index 'movies', activating 'movies-1' because you said so.
假设您已经实现了
get reindex\u迭代器,那么您可以调用
/manage.py es_update
更新索引。
$> ./manage.py es_update movies
Handling update of index 'movies' using its active index version 'movies-1'
Checking the last time update was called:
- index version: movies-1
- update date: never
Getting Reindex Iterator...
Completed with indexing movies-1
$> ./manage.py es_list
Available Index Definitions:
+----------------------+-------------------------------------+---------+--------+-------+-----------+
| Index Base Name | Index Version Name | Created | Active | Docs | Tag |
+======================+=====================================+=========+========+=======+===========+
| movies | movies-1 | 1 | 1 | 3 | 07.11.005 |
| | | | | | -93-gd101 |
| | | | | | a1f |
+----------------------+-------------------------------------+---------+--------+-------+-----------+
< > >
pip install django elastic migrations ;请参见pypi上的 django elastic migrations 。
在 requirements.txt中引用此包
确保可访问有效的elasticsearch dsl py版本,并进行配置 Django设置中配置的ElasticSearch Singleton客户端的路径: django_elastic_migrations_es_client="tests.es_config.es_client" 。 在您的应用程序中应该只有一个实例化的es_客户端。
将django弹性迁移添加到django中已安装的应用程序中 设置文件
将以下信息添加到django设置文件:
DJANGO_ELASTIC_MIGRATIONS_ES_CLIENT = "path.to.your.singleton.ES_CLIENT" # optional, any unique number for your releases to associate with indexes DJANGO_ELASTIC_MIGRATIONS_GET_CODEBASE_ID = subprocess.check_output(['git', 'describe', "--tags"]).strip() # optional, can be used to have multiple servers share the same # elasticsearch instance without conflicting DJANGO_ELASTIC_MIGRATIONS_ENVIRONMENT_PREFIX = "qa1_"
通过运行 /manage.py migrate创建 django_elastic_migrations 表
创建一个 demindex :
from django_elastic_migrations.indexes import DEMIndex, DEMDocType from .models import Movie from elasticsearch_dsl import Text MoviesIndex = DEMIndex('movies') @MoviesIndex.doc_type class MovieSearchDoc(DEMDocType): text = TEXT_COMPLEX_ENGLISH_NGRAM_METAPHONE @classmethod def get_queryset(self, last_updated_datetime=None): """ return a queryset or a sliceable list of items to pass to get_reindex_iterator """ qs = Movie.objects.all() if last_updated_datetime: qs.filter(last_modified__gt=last_updated_datetime) return qs @classmethod def get_reindex_iterator(self, queryset): return [ MovieSearchDoc( text="a little sample text").to_dict( include_meta=True) for g in queryset]
将新索引添加到settings/common.py中的django_elastic_migrations_index
运行 /manage.py es_list以查看可用的索引:
./manage.py es_list Available Index Definitions: +----------------------+-------------------------------------+---------+--------+-------+-----------+ | Index Base Name | Index Version Name | Created | Active | Docs | Tag | +======================+=====================================+=========+========+=======+===========+ | movies | | 0 | 0 | 0 | Current | | | | | | | (not | | | | | | | created) | +----------------------+-------------------------------------+---------+--------+-------+-----------+ Reminder: an index version name looks like 'my_index-4', and its base index name looks like 'my_index'. Most Django Elastic Migrations management commands take the base name (in which case the activated version is used) or the specific index version name.
使用 /manage.py es_create movies在elasticsearch中创建 电影 索引:
$> ./manage.py es_create movies The doc type for index 'movies' changed; created a new index version 'movies-1' in elasticsearch. $> ./manage.py es_list Available Index Definitions: +----------------------+-------------------------------------+---------+--------+-------+-----------+ | Index Base Name | Index Version Name | Created | Active | Docs | Tag | +======================+=====================================+=========+========+=======+===========+ | movies | movies-1 | 1 | 0 | 0 | 07.11.005 | | | | | | | -93-gd101 | | | | | | | a1f | +----------------------+-------------------------------------+---------+--------+-------+-----------+ Reminder: an index version name looks like 'my_index-4', and its base index name looks like 'my_index'. Most Django Elastic Migrations management commands take the base name (in which case the activated version is used) or the specific index version name.
激活 movies-1索引版本,以便所有更新和读取都转到它。
./manage.py es_activate movies For index 'movies', activating 'movies-1' because you said so.
假设您已经实现了 get reindex\u迭代器,那么您可以调用 /manage.py es_update 更新索引。
$> ./manage.py es_update movies Handling update of index 'movies' using its active index version 'movies-1' Checking the last time update was called: - index version: movies-1 - update date: never Getting Reindex Iterator... Completed with indexing movies-1 $> ./manage.py es_list Available Index Definitions: +----------------------+-------------------------------------+---------+--------+-------+-----------+ | Index Base Name | Index Version Name | Created | Active | Docs | Tag | +======================+=====================================+=========+========+=======+===========+ | movies | movies-1 | 1 | 1 | 3 | 07.11.005 | | | | | | | -93-gd101 | | | | | | | a1f | +----------------------+-------------------------------------+---------+--------+-------+-----------+
部署
- 在部署之前,可以创建和更新新的索引架构。 例如,如果您的应用服务器运行时激活了 movies-1 索引,则 使用要预索引的架构的新版本,然后登录到另一个 服务器并运行 /manage.py es_create movies 然后 /manage.py es_update movies更新电影。这将更新所有 电影中的文档 比活动索引更新的索引。
- 部署后,可以运行 /manage.py es_activate movies 激活最新版本。一定要骑自行车 Gunicorn工作人员确保应用服务器捕获更改。
- 在部署期间,如果get_reindex_iterator 是以响应的方式实现的 到上次重新索引日期的日期时间,然后可以调用 /manage.py es_update movies --resume ,它将只索引那些具有 自上次重新编制索引以来已更改。这样你就能提前完成大部分的索引工作, 并且仅在展开时重新索引一部分。
django测试
(可选)在 你的django设置。默认的测试前缀是 测试。每个 测试将创建自己的索引。
if 'test' in sys.argv: DJANGO_ELASTIC_MIGRATIONS_ENVIRONMENT_PREFIX = 'test_'
重写测试用例- test_utilities.py
from django_elastic_migrations import DEMIndexManager class MyTestCase(TestCase): def _pre_setup(self): DEMIndexManager.test_pre_setup() super(MyTestCase, self)._pre_setup() def _post_teardown(self): DEMIndexManager.test_post_teardown() super(MyTestCase, self)._post_teardown()
< > >
从django的 dumpdata 命令中排除
调用django的dumpdata命令时, 您可能希望排除此应用程序中使用的数据库表:
from django.core.management import call_command params = { 'database': 'default', 'exclude': [ # we don't want to include django_elastic_migrations in dumpdata, # because it's environment specific 'django_elastic_migrations.index', 'django_elastic_migrations.indexversion', 'django_elastic_migrations.indexaction' ], 'indent': 3, 'output': 'path/to/my/file.json' } call_command('dumpdata', **params)
此示例包含在 moviegen管理命令