Skip to content

Commit 27ce831

Browse files
MrTangokobros-tech
authored andcommitted
[16.0][Add] connector_typesense: a connector to typsense search engine
1 parent 3c90caf commit 27ce831

24 files changed

Lines changed: 1540 additions & 0 deletions

connector_typesense/README.rst

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
===================
2+
connector_typesense
3+
===================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:f09633c3af59b153f0eba3f876a9835676c430a6f39dd0dfa3545a924c80bc11
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsearch--engine-lightgray.png?logo=github
20+
:target: https://github.com/OCA/search-engine/tree/16.0/connector_typesense
21+
:alt: OCA/search-engine
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/search-engine-16-0/search-engine-16-0-connector_typesense
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/search-engine&target_branch=16.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This addon provides the bases to implement addons to export information to
32+
Typesense_ indexes.
33+
34+
.. _Typesense: https://typesense.org
35+
36+
**Table of contents**
37+
38+
.. contents::
39+
:local:
40+
41+
Installation
42+
============
43+
44+
This addon uses the native json python package provided by python. When
45+
a json for a record is recomputed, the new value is compared to the original
46+
one to see if an export to the search engine index is needed. This is
47+
done by comparing the md5 of the two json strings. This process when done on
48+
a large number of records can be slow when the json is large and complex. To speed
49+
up this process you can install the orjson package.
50+
51+
.. code-block:: bash
52+
53+
pip install orjson
54+
55+
This package requires a typesense search engine running.
56+
Please read this for a [quick docker based setup](https://typesense.org/docs/guide/install-typesense.html#option-2-local-machine-self-hosting).
57+
58+
Usage
59+
=====
60+
61+
Overview
62+
~~~~~~~~
63+
64+
A search engine is a system designed to store information in a way that makes
65+
it easy to find through search and analytics queries. The main difference
66+
between a search engine and a database is that a search engine is optimized
67+
for search and analytics queries, while a database is optimized for
68+
transactional and relational queries.
69+
70+
This addons is designed around 4 main concepts:
71+
72+
* **The search engine backend** is used to define into Odoo the kind
73+
of search engine that will be used to index the data. It's main responsibility
74+
is to provide an instance of `odoo.addons.search_engine.tools.adapter.SearchEngineAdapter`
75+
that will be used to communicate with the search engine.
76+
77+
* **The search engine index** is used to define into Odoo the index where
78+
the data will be indexed. An index is always linked to a search engine backend.
79+
The index provides methods to use to manage the lifecycle of the data put into
80+
the index for the records of a given model. To do so, it uses:
81+
82+
* **The SearchEngineAdapter** provided by the backend to communicate with the
83+
search engine.
84+
* **A ModelSerializer** that is used to transform an odoo record into
85+
a dictionary that can be indexed into the search engine.
86+
* **A JsonValidator** that is used to validate the data that is to be
87+
indexed into the search engine.
88+
89+
The RecordSerializer and IndexDataValidator are defined on the index itself.
90+
The current addon provides a default implementation only for the IndexDataValidator.
91+
You can find into the github repository `search-engine <https://github.com:
92+
OCA/search-engine/tree/16.0>`_ An implementation of the RecordSerializer based
93+
on the jsonifier addon `connector_search_engine_jsonifier`.
94+
95+
* **The search engine indexable record** is a mixin that is used to define
96+
the records that can be indexed into a search engine index. The mixin
97+
provides methods:
98+
99+
* To add a record to an index.
100+
* To remove a record from an index.
101+
* To mark the record into an index (*the search engine bindings*) as to be
102+
recomputed (This method should be called when modifications are made on
103+
the record that could impact the data that are indexed into the search
104+
engine. It will instruct the index that the record must be recomputed and
105+
re-indexed).
106+
107+
It also ensures that when the record is unlinked, it is removed from the indexes
108+
it was indexed into.
109+
110+
* **The search engine binding** is a model that represents the link between
111+
an index and an indexable odoo record. It give you access to the data
112+
that are indexed into the search engine for the record. It's also used to
113+
manage the lifecycle of the data into the search engine. When a binding is
114+
created, it's marked as to be computed. Once the data are computed, the
115+
binding is marked as to be indexed. Once the data are indexed, the binding
116+
is marked as indexed. If the linked record is unlinked, the binding is
117+
marked as to be removed. Once the data are removed from the search engine,
118+
the binding is deleted.
119+
120+
Indexing lifecycle
121+
~~~~~~~~~~~~~~~~~~
122+
123+
The indexing lifecycle is based on the following steps:
124+
125+
* When a record is added to an index, a binding is created and marked as to be
126+
computed.
127+
* A cron job scheduled every 5 minutes will look for bindings that are to be
128+
computed and for each of them will schedule a job to re compute the json data.
129+
* When the json data is computed, the binding is marked as to be exported if the
130+
json is valid and is different from the one that has been computed last time.
131+
* A cron job scheduled every 5 minutes will ensure the syncing with the search
132+
engine. It will:
133+
134+
* look for bindings that are to be exported and for each of them will schedule
135+
a job to export the json data into the search engine. Once exported, the
136+
binding is marked as 'done'.
137+
* look for bindings that are to be removed and for each of them will schedule
138+
a job to remove the data from the search engine. Once removed, the binding
139+
is deleted.
140+
141+
To keep in sync the data from your model instance and the data that are indexed
142+
into the search engine, you should call the method `_se_mark_to_update` on the
143+
mode instance when you make modifications that could impact the data that are
144+
indexed into the search engine.
145+
146+
* When the method `_se_mark_to_update` is called, the binding is marked as to be
147+
computed.
148+
* From there, the same process as described above will be used to recompute the
149+
data and reindex them into the search engine.
150+
151+
When a model instance is unlinked, the binding is marked as to be removed. From
152+
there if will be processed by the job syncing the data with the search engine.
153+
154+
.. note::
155+
156+
In previous versions of this addon, there was no method to mark a record as
157+
to be recomputed. As a consequence, all the records were re-computed every day
158+
to ensure that the data in the search engine were up to date. This was a
159+
performance issue and consumed a lot of resources. If despite this, you want
160+
to recompute all the records every day, you can activate the cron jon
161+
`Search engine: recompute all index` and deactivate the one named
162+
`earch engine: Generate job for recompute binding to recompute per index`.
163+
164+
Known issues / Roadmap
165+
======================
166+
167+
* Implement generic trigger for binding
168+
based on ir.export linked to the index
169+
(the aim is to set the binding to be updated
170+
if we modify a field configured in the exporter)
171+
172+
Changelog
173+
=========
174+
175+
16.0.0.1.1 (2023-10-13)
176+
~~~~~~~~~~~~~~~~~~~~~~~
177+
178+
**Bugfixes**
179+
180+
- Fixes cache issue with the *se_binding_ids* field on the *s.indexable.record*
181+
model. When a binding is created or updated or deleted, the cache for the
182+
*se_binding_ids* field for referenced records is now invalidated. That way,
183+
the next time the field is accessed after such an operation, the value is
184+
recomputed to reflect the change. (`#163 <https://github.com/OCA/search-engine/issues/163>`_)
185+
186+
187+
16.0.0.1.0 (2023-10-13)
188+
~~~~~~~~~~~~~~~~~~~~~~~
189+
190+
**Features**
191+
192+
- A new action **Update state** is now available on *Search Engine Record* objects.
193+
This action allows you to update the state of selected records on the tree view.
194+
195+
Add a smart button to quickly access to the bound records from the
196+
*Search Engine Backend* and *Search Engine Record* views. (`#162 <https://github.com/OCA/search-engine/issues/162>`__)
197+
198+
199+
**Bugfixes**
200+
201+
- Fix Search Engine Binding form view. The fields data and error are now
202+
properly displayed and fit the width of the form.
203+
204+
Makes the Odoo's admin user a member of the *Search Engine Connector Manager* group. (`#162 <https://github.com/OCA/search-engine/issues/162>`__)
205+
206+
207+
12.0.x.y.z (YYYY-MM-DD)
208+
~~~~~~~~~~~~~~~~~~~~~~~
209+
210+
TODO
211+
212+
Bug Tracker
213+
===========
214+
215+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/search-engine/issues>`_.
216+
In case of trouble, please check there if your issue has already been reported.
217+
If you spotted it first, help us to smash it by providing a detailed and welcomed
218+
`feedback <https://github.com/OCA/search-engine/issues/new?body=module:%20connector_typesense%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
219+
220+
Do not contact contributors directly about support or help with technical issues.
221+
222+
Credits
223+
=======
224+
225+
Authors
226+
~~~~~~~
227+
228+
* Derico
229+
230+
Contributors
231+
~~~~~~~~~~~~
232+
233+
* Sébastien BEAU <sebastien.beau@akretion.com>
234+
* Laurent Mignon <laurent.mignon@acsone.eu>
235+
* Simone Orsi <simone.orsi@camptocamp.com>
236+
* Raphaël Reverdy <raphael.reverdy@akretion.com>
237+
* Maik Derstappen <md@derico.de>
238+
* Mohamed Alkobrosli <malkobrosly@kencove.com>
239+
240+
Maintainers
241+
~~~~~~~~~~~
242+
243+
This module is maintained by the OCA.
244+
245+
.. image:: https://odoo-community.org/logo.png
246+
:alt: Odoo Community Association
247+
:target: https://odoo-community.org
248+
249+
OCA, or the Odoo Community Association, is a nonprofit organization whose
250+
mission is to support the collaborative development of Odoo features and
251+
promote its widespread use.
252+
253+
This module is part of the `OCA/search-engine <https://github.com/OCA/search-engine/tree/16.0/connector_typesense>`_ project on GitHub.
254+
255+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

connector_typesense/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import models
2+
from . import tools
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copyright 2024 Derico
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
{
5+
"name": "connector_typesense",
6+
"category": "Connector",
7+
"summary": "Connector For Typesense Search Engine",
8+
"version": "16.0.0.0.2",
9+
"license": "AGPL-3",
10+
"author": "Derico, Odoo Community Association (OCA)",
11+
"website": "https://github.com/OCA/search-engine",
12+
"depends": ["connector_search_engine"],
13+
"data": [
14+
"views/ts_backend.xml",
15+
],
16+
"demo": ["demo/se_index_config_demo.xml", "demo/backend_demo.xml"],
17+
"external_dependencies": {"python": ["typesense==1.0.3", "requests"]},
18+
"installable": True,
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<!-- Copyright 2019 ACSONE SA/NV
3+
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
4+
<odoo>
5+
<record id="backend_1" model="se.backend">
6+
<field name="name">Demo Sale Channel Typesense</field>
7+
<field name="tech_name">demo_sale_channel_typesense</field>
8+
<field name="backend_type">typesense</field>
9+
<field name="ts_server_host">localhost</field>
10+
<field name="ts_server_port">8108</field>
11+
<field name="ts_server_protocol">http</field>
12+
<field name="ts_api_key">xyz</field>
13+
</record>
14+
</odoo>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<odoo>
3+
<record id="se_index_config_product" model="se.index.config">
4+
<field name="name">TS Product Config</field>
5+
<field name="body">{}</field>
6+
<field name="body_str">
7+
{
8+
"name": "ts_products_collection",
9+
"fields": [
10+
{
11+
"name": "product_id",
12+
"type": "int32"
13+
},
14+
{
15+
"name": "name",
16+
"type": "string"
17+
}
18+
],
19+
"default_sorting_field": "product_id"
20+
}
21+
</field>
22+
</record>
23+
</odoo>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import ts_backend, ts_index
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright 2024 Derico
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
from ..tools.adapter import TypesenseAdapter
7+
8+
9+
class SeBackend(models.Model):
10+
_inherit = "se.backend"
11+
12+
backend_type = fields.Selection(
13+
selection_add=[("typesense", "Typesense")],
14+
ondelete={"typesense": "cascade"},
15+
string="Type",
16+
required=True,
17+
)
18+
ts_server_host = fields.Char(
19+
string="Typesense host",
20+
groups="connector_search_engine.group_connector_search_engine_manager",
21+
)
22+
ts_server_port = fields.Char(
23+
string="Typesense port",
24+
groups="connector_search_engine.group_connector_search_engine_manager",
25+
)
26+
ts_server_protocol = fields.Char(
27+
string="Typesense protocol",
28+
groups="connector_search_engine.group_connector_search_engine_manager",
29+
)
30+
ts_server_timeout = fields.Integer(
31+
string="Typesense server timeout",
32+
groups="connector_search_engine.group_connector_search_engine_manager",
33+
)
34+
ts_api_key = fields.Char(
35+
help="Typesense Api Key",
36+
groups="connector_search_engine.group_connector_search_engine_manager",
37+
)
38+
39+
def _get_adapter_class(self):
40+
if self.backend_type == "typesense":
41+
return TypesenseAdapter
42+
else:
43+
return super()._get_adapter_class()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright 2024 Derico
2+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3+
4+
from odoo import models
5+
6+
7+
class SeIndex(models.Model):
8+
9+
_inherit = "se.index"

0 commit comments

Comments
 (0)