Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions base_sparse_field_jsonb_search/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
## Introduction

This module enables native PostgreSQL JSONB search operators for sparse fields stored in
Serialized containers.

When combined with `base_sparse_field_jsonb`, which upgrades Serialized fields from TEXT
to JSONB storage, this module translates Odoo search domains into native PostgreSQL
JSONB operators for significantly improved query performance.

## Performance Improvement

Without this module, searching on sparse fields requires:

1. Loading all records from the database
2. Deserializing JSON data in Python
3. Filtering records in Python memory

With this module, the same search uses native PostgreSQL:

```sql
-- Native JSONB query (fast, uses GIN index)
SELECT * FROM product_template
WHERE x_custom_json->>'x_color' = 'red'
```

## Supported Operators

| Odoo Operator | JSONB Translation |
| -------------------- | ------------------------------- |
| `=` | `jsonb->>'key' = 'value'` |
| `!=` | `jsonb->>'key' != 'value'` |
| `in` | `jsonb->>'key' IN (...)` |
| `not in` | `jsonb->>'key' NOT IN (...)` |
| `like` | `jsonb->>'key' LIKE '%value%'` |
| `ilike` | `jsonb->>'key' ILIKE '%value%'` |
| `>`, `>=`, `<`, `<=` | Numeric cast + comparison |

## Boolean Fields

Boolean sparse fields are handled specially:

```sql
-- Check if boolean field is True
WHERE (jsonb->'field')::boolean = TRUE

-- Check if boolean field is False or not set
WHERE (jsonb->'field' IS NULL OR (jsonb->'field')::boolean = FALSE)
```

## Usage

## Automatic Activation

This module auto-installs when `base_sparse_field_jsonb` is installed. No additional
configuration is required.

## How It Works

When you search on a model with sparse fields:

```python
# Standard Odoo search on a sparse field
products = self.env['product.template'].search([
('x_color', '=', 'red'),
('x_manufacturing_year', 'in', ['2022', '2023', '2024']),
])
```

The module automatically:

1. Detects that `x_color` and `x_manufacturing_year` are sparse fields
2. Identifies their container field (e.g., `x_custom_json`)
3. Translates the domain to JSONB operators
4. Executes the query using PostgreSQL's GIN index

## Debugging

Enable debug logging to see the JSONB translations:

```python
import logging
logging.getLogger('odoo.addons.base_sparse_field_jsonb_search').setLevel(logging.DEBUG)
```

This will log messages like:

```
JSONB search: product_template.x_color = 'red' -> x_custom_json->>'x_color'
```

## Limitations

- Sorting on sparse fields is not supported (would require additional indexes)
- Complex nested JSON paths are not supported
- Full-text search requires additional configuration

## Contributors

- OBS Solutions B.V. <https://www.obs-solutions.com>
- Stefcy <hello@stefcy.com>

## Credits

## Development

This module was developed by OBS Solutions B.V.
194 changes: 194 additions & 0 deletions base_sparse_field_jsonb_search/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

==============================
Base Sparse Field JSONB Search
==============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:616a86600d04410afe4aa253e949cb8c75c79e513145b2f1a98812a1fd60be8f
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
:target: https://github.com/OCA/server-tools/tree/19.0/base_sparse_field_jsonb_search
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-tools-19-0/server-tools-19-0-base_sparse_field_jsonb_search
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=19.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module enables native PostgreSQL JSONB search operators for sparse
fields stored in Serialized containers.

When combined with ``base_sparse_field_jsonb``, which upgrades
Serialized fields from TEXT to JSONB storage, this module translates
Odoo search domains into native PostgreSQL JSONB operators for
significantly improved query performance.

Performance Improvement
-----------------------

Without this module, searching on sparse fields requires:

1. Loading all records from the database
2. Deserializing JSON data in Python
3. Filtering records in Python memory

With this module, the same search uses native PostgreSQL:

.. code:: sql

-- Native JSONB query (fast, uses GIN index)
SELECT * FROM product_template
WHERE x_custom_json->>'x_color' = 'red'

Supported Operators
-------------------

============================ =================================
Odoo Operator JSONB Translation
============================ =================================
``=`` ``jsonb->>'key' = 'value'``
``!=`` ``jsonb->>'key' != 'value'``
``in`` ``jsonb->>'key' IN (...)``
``not in`` ``jsonb->>'key' NOT IN (...)``
``like`` ``jsonb->>'key' LIKE '%value%'``
``ilike`` ``jsonb->>'key' ILIKE '%value%'``
``>``, ``>=``, ``<``, ``<=`` Numeric cast + comparison
============================ =================================

Boolean Fields
--------------

Boolean sparse fields are handled specially:

.. code:: sql

-- Check if boolean field is True
WHERE (jsonb->'field')::boolean = TRUE

-- Check if boolean field is False or not set
WHERE (jsonb->'field' IS NULL OR (jsonb->'field')::boolean = FALSE)

**Table of contents**

.. contents::
:local:

Usage
=====

Automatic Activation
--------------------

This module auto-installs when ``base_sparse_field_jsonb`` is installed.
No additional configuration is required.

How It Works
------------

When you search on a model with sparse fields:

.. code:: python

# Standard Odoo search on a sparse field
products = self.env['product.template'].search([
('x_color', '=', 'red'),
('x_manufacturing_year', 'in', ['2022', '2023', '2024']),
])

The module automatically:

1. Detects that ``x_color`` and ``x_manufacturing_year`` are sparse
fields
2. Identifies their container field (e.g., ``x_custom_json``)
3. Translates the domain to JSONB operators
4. Executes the query using PostgreSQL's GIN index

Debugging
---------

Enable debug logging to see the JSONB translations:

.. code:: python

import logging
logging.getLogger('odoo.addons.base_sparse_field_jsonb_search').setLevel(logging.DEBUG)

This will log messages like:

::

JSONB search: product_template.x_color = 'red' -> x_custom_json->>'x_color'

Limitations
-----------

- Sorting on sparse fields is not supported (would require additional
indexes)
- Complex nested JSON paths are not supported
- Full-text search requires additional configuration

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-tools/issues/new?body=module:%20base_sparse_field_jsonb_search%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* OBS Solutions B.V.

Contributors
------------

- OBS Solutions B.V. https://www.obs-solutions.com
- Stefcy hello@stefcy.com

Other credits
-------------

Development
~~~~~~~~~~~

This module was developed by OBS Solutions B.V.

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/19.0/base_sparse_field_jsonb_search>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions base_sparse_field_jsonb_search/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
15 changes: 15 additions & 0 deletions base_sparse_field_jsonb_search/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Base Sparse Field JSONB Search",
"version": "19.0.1.0.0",
"category": "Technical",
"summary": "Enable native PostgreSQL JSONB operators in Odoo search domains",
"author": "OBS Solutions B.V., Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
"license": "LGPL-3",
"depends": [
"base_sparse_field_jsonb",
],
"data": [],
"installable": True,
"auto_install": True,
}
2 changes: 2 additions & 0 deletions base_sparse_field_jsonb_search/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import base_model
from . import expression_patch
Loading
Loading