Skip to content

[16.0][ADD] Connector typesense #203

Closed
kobros-tech wants to merge 1 commit into
OCA:16.0from
kencove:connector_typesense
Closed

[16.0][ADD] Connector typesense #203
kobros-tech wants to merge 1 commit into
OCA:16.0from
kencove:connector_typesense

Conversation

@kobros-tech
Copy link
Copy Markdown
Contributor

based on

#168

@OCA-git-bot
Copy link
Copy Markdown
Contributor

Hi @lmignon,
some modules you are maintaining are being modified, check this out!

@kobros-tech kobros-tech force-pushed the connector_typesense branch 7 times, most recently from 1ddc5f3 to 27ce831 Compare April 16, 2025 13:57
@kobros-tech kobros-tech force-pushed the connector_typesense branch 10 times, most recently from 4424191 to 5e79387 Compare April 21, 2025 16:52
@kobros-tech
Copy link
Copy Markdown
Contributor Author

@lmignon
@wlin-kencove
@dnplkndll

Can we have this module reviewed?

@kobros-tech
Copy link
Copy Markdown
Contributor Author

@lmignon
@sbidoul

I am planning to benefit from shopinvader serializing, shall we cooperate to produce a module relying on it here or I would rely on my effort alone?

I only need your repo to be available here or create a specific one in OCA?

Comment thread connector_typesense/models/se_backend.py
Copy link
Copy Markdown
Contributor

@lmignon lmignon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some little comments but otherwise looks good.

Comment thread connector_typesense/models/se_index.py Outdated
Comment thread connector_typesense/tests/test_connector_typesense.py
@lmignon
Copy link
Copy Markdown
Contributor

lmignon commented Apr 23, 2025

@lmignon @sbidoul

I am planning to benefit from shopinvader serializing, shall we cooperate to produce a module relying on it here or I would rely on my effort alone?

I only need your repo to be available here or create a specific one in OCA?

@kobros-tech You could also contribute on the shopinvader repo. Shopinvader contributors are all OCA members. All these modules could have been developed under the OCA and follow the same rules as those put in place by this organization. For the time being, however, they are managed in an independent repo for historical reasons, but also because they are designed to meet a specific context of use. It should be noted that all low-level modules are in the OCA, and are the result of the major architectural work we have carried out and continue to carry out for Shopinvader: connector_searchengine, fs_, fastapi and pydantic integrations in Odoo, (base_rest, storage_) etc... This situation is not set in stone and is open to discussion.

@kobros-tech
Copy link
Copy Markdown
Contributor Author

all right, I will review changes

For me, I am thinking of high mobility connection instead of creating a new module for each new serialised field.

ir.exports with serialozers module have a solution but need some improvement and interactive dialogs, I am working on that in a new module here and PR referring to this one.

I could only benefit from shopinvader by documenting each field but later on.

Thanks @lmignon

@kobros-tech kobros-tech force-pushed the connector_typesense branch 2 times, most recently from ae63122 to ba7b886 Compare April 23, 2025 17:06
@kobros-tech kobros-tech force-pushed the connector_typesense branch 2 times, most recently from a279875 to 50567db Compare May 4, 2025 00:01
@codeagencybe
Copy link
Copy Markdown
Member

all right, I will review changes

For me, I am thinking of high mobility connection instead of creating a new module for each new serialised field.

ir.exports with serialozers module have a solution but need some improvement and interactive dialogs, I am working on that in a new module here and PR referring to this one.

I could only benefit from shopinvader by documenting each field but later on.

Thanks @lmignon

This module can be interesting for odoo website/ecommerce as well, not just shopinvader. Even for other headless use cases to consume Typesense for search + filtering in a shop.

I was about to consider to create a module for meillisearch. Very similar to Typesense.

Is there any final decision where the module is going? Is there also a v18 migration yet or planned?

@kobros-tech
Copy link
Copy Markdown
Contributor Author

@codeagencybe

thanks, if you are an OCA member you could review the module as we always do as OCA members for the modules that are interesting.

As long as you like it and wishing to have a 18.0 migration, you can help to get this one merged first and then anybody will work on migration to 18.0 like me as planned.

I am not interested in shopinader after creating this #204 module which saves me +50 not needed modules!

I know Fabio that you use shopinvader, but I am not using it and to have one module to serialize all search engine I wish you succeed with this idea.

Good Luck Fabio and I wish you have recovered from Covid.

Copy link
Copy Markdown

@thienvh332 thienvh332 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update! I’ve reviewed the changes once again and tested the functionality, everything is working smoothly on my end 👍

I found a few places where we could make some updates.
Nothing blocking, just some nitpicking 😉

Comment thread connector_typesense/__manifest__.py Outdated
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2019 ACSONE SA/NV
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<!-- Copyright 2019 ACSONE SA/NV
<!-- Copyright 2024 Derico

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in fact none of them deserve the copy right except they had the first trial, but Kencove is doing the action on it now.

Comment thread connector_typesense/tools/adapter.py
Comment thread connector_typesense/readme/CONTRIBUTORS.rst Outdated
Comment thread connector_typesense/tools/adapter.py
Comment thread connector_typesense/tools/adapter.py Outdated
Comment on lines +113 to +111
def delete(self, binding_ids) -> None:
ts = self._ts_client
for binding_id in binding_ids:
try:
ts.collections[self._index_name].documents[f"{binding_id}"].delete()
except typesense.exceptions.ObjectNotFound as e:
_logger.info(
f"Could not find a document with id: '{binding_id}'... \n{e}"
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each call to ts.collections[self._index_name].documents[f"{binding_id}"].delete() sends a separate request.
This approach may be inefficient when deleting a large number of documents.

Proposal: Use delete-by-query instead for better performance.

Example:

ts.collections[self._index_name].documents.delete(filter=f"id:{binding_ids}")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I was not relying on id filter while building up the module, but now as it is functioning well and has its own serializer to convert id value into string, I may use it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling filter method how can be faster that calling the exact document by its id directly, I am not sure.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking about the issue of deleting multiple records at once.
For example, deleting 100 records: with the initial approach, the server would send 100 separate HTTP requests. Do you think we need to address this issue?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO I there is a more efficient option we should implement it.
https://typesense.org/docs/28.0/api/documents.html#delete-a-single-document
I only see the record and query options though?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dnplkndll ,
I also referred to that documentation. You can scroll down a bit to the 'delete-by-query' section and you'll see a 'TIP' part.
image

Actually, this doesn't block anything, it's just a suggestion for improvement.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can understand you mean we make just a single API call to delete all recordsets we have instead of looping through them and making API call for each?

It is a fantastic idea, thanks!

@kobros-tech kobros-tech force-pushed the connector_typesense branch from 50567db to 147f7f5 Compare May 13, 2025 12:33
@kobros-tech
Copy link
Copy Markdown
Contributor Author

try to see what happens, if the issue arises raise it against the base module as all methods here are managed by cron and queued jobs.

@kobros-tech kobros-tech force-pushed the connector_typesense branch from 147f7f5 to 6e59027 Compare May 15, 2025 23:32
@sebastienbeau sebastienbeau added this to the 16.0 milestone Jun 3, 2025
Comment on lines +13 to +19
serializer_type = fields.Selection(selection_add=[("typesense", "Typesense")])

def _get_serializer(self):
if self.serializer_type == "typesense":
return TSJsonifySerializer()
else:
return super()._get_serializer()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It do not make sense to add a serializer here.
Serializer are not "linked" to a kind of search engine, but more on a kind of usage "shopinvader" for example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shopinvader is doing the same by the way in its custom modules

but I am not following shopinvader as it looks old technique and hard code serialzing but I do dynamic serialzing.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will better to add a "dynamic serialer" in a separated module, because the serializer is not related to typesense (it can be used for other search engine

Copy link
Copy Markdown
Contributor

@lmignon lmignon Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shopinvader is doing the same by the way in its custom modules

but I am not following shopinvader as it looks old technique and hard code serialzing but I do dynamic serialzing.

@kobros-tech

old technique 🤔 We follow a different pattern but not an old technique since in v8 we started with dynamic serializing using the base_jsonify... The uses of pre-defined models is motivated by:

  • the need to control the format and the content exported to the search engine to avoid any leak of information. * the need to provide the documentation related to the data exported
  • define a strict contract between Odoo and ES (If the internal model of odoo evolve when migrating from one version to another, we are sure to not break the website since the mapping is explicit and our unittest will fails)
  • ...

There are no old and new or right and wrong approaches. It all depends on individual needs and sensitivities. With this in mind, the architecture of these modules has been designed to allow easy adaptation to individual needs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry, I can't compare one single module to a project :)

Comment thread connector_typesense/tools/adapter.py
Comment thread connector_typesense/tools/adapter.py
@sebastienbeau
Copy link
Copy Markdown
Member

Hi sorry for the delay for the review.

Thanks a lot for helping on this PR ! And thanks for your interest in the project

This week I want to focus on this PR in order to get it merged ! So I can help to fix it and test it.
Are you able for fixing stuff this days? If not I can do it (I am at the OCA spain code sprint, and so available for doing it).

Instead of squashing all in one commit can you do one commit for work done by @MrTango and one for the work done by you ? (it's always better for historic purpose)

Regarding the fact of having generic module for the serializer for the search engine. I am not closed on this idea.
On shopinvader we decide to move on Pydantic schema as default exporter. And so, most of shopinvader related schema module are already split on small module so right now you do not need to install all the shopinvader stack for having the schema, you just have to install related schema and search engine module.
But for sure there is a "lot" of module for the search engine part (as it's small module that just extend an existing schema).

@kobros-tech
Copy link
Copy Markdown
Contributor Author

I don't think it is following OCA rules

only merged commits can't be squashed or the commits that can introduce fix to issues in many branches

but the old commits were not fixes but they were just trials

@sebastienbeau
Copy link
Copy Markdown
Member

For OCA there is no issue with having 2 commits.
Right now there is only one commit where @MrTango is the author so you work is "invisible" and if somebody do a rebase you will not appear anymore in git history.
So this is why I think it's clearer to keep at least 2 commits one with the work of @MrTango and one with your work.

I can do it if you want, I do not want to add you extra work, I just want to add your credit in git history ;)

@kobros-tech
Copy link
Copy Markdown
Contributor Author

For OCA there is no issue with having 2 commits. Right now there is only one commit where @MrTango is the author so you work is "invisible" and if somebody do a rebase you will not appear anymore in git history. So this is why I think it's clearer to keep at least 2 commits one with the work of @MrTango and one with your work.

I can do it if you want, I do not want to add you extra work, I just want to add your credit in git history ;)

thanks very much

I respect this of you
In fact I preferred to ignore myself if someone complains but as long as you don't mind I also don't mind

@sebastienbeau
Copy link
Copy Markdown
Member

I prefer to split in two commit, so it's easier to review, also it will make easier for @MrTango to review the change.
I am going to do a PR, and also to propose some extra refactoring.

@sebastienbeau sebastienbeau mentioned this pull request Jun 4, 2025
1 task
@sebastienbeau
Copy link
Copy Markdown
Member

Note: as a best practice for the review, the best should have been to open a PR on the branch of @MrTango so we can review it, and merge it in his PR. But don't worry it's just a tips for the next time.

Any case thank for you contribution and your time. I am starting some review / refactoring here : #210, I should have something ready tomorrow

@MrTango
Copy link
Copy Markdown
Contributor

MrTango commented Jun 4, 2025

Good to see progress here. Unfortunately i can't spend time this and next week. But I'll have a look at the situation in a couple of weeks and plan to sprint on it latest in Liege.

@kobros-tech
Copy link
Copy Markdown
Contributor Author

Note: as a best practice for the review, the best should have been to open a PR on the branch of @MrTango so we can review it, and merge it in his PR. But don't worry it's just a tips for the next time.

Any case thank for you contribution and your time. I am starting some review / refactoring here : #210, I should have something ready tomorrow

I think before I start this PR I told them in the first original one, for me I don't care who does what as much as the work be good and everybody's work is remembered.

For opening a new PR I am used to not just with others but with myself, sometimes I don't trust one migration and proposes the other and discuss until we merge the best accepted version.

I put into account others yes, as you saw the commit was not having my name.

As long as I see interest and activity I am happy too.

@sebastienbeau
Copy link
Copy Markdown
Member

Replaced by : #210

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants