简体   繁体   中英

MYSQL - How to search in JSON array?

On my Symfony 5 app, i've a database with a candidate table that contains a json field.

candidate 1 : [{"end": "30/04/2020", "start": "01/03/2020"},{"end": "31/07/2020", "start": "01/07/2020"}]

candidate 2 : [{"end": "31/03/2020", "start": "01/03/2020"},{"end": "31/07/2020", "start": "01/07/2020"}]

Is it possible with query builder to find a candidate where this field corresponds to the arguments ?

ex: I would like to find all the candidates who are available between 10/03/2020 and 10/04/2020. This case should just return the candidate 1.

I guess it's not possible to do this with query builder so i'm trying to use native SQL but... what's the sql syntax ?

I tried with availability_dates`->"$.start" = "01/03/2020" but it does not work because it's a "collection".

This is a poorly-conceived database structure. Clearly, the JSON string represents a "repeating group" of related data, which violates the principles of so-called "normal forms."

https://en.wikipedia.org/wiki/Database_normalization

You should be storing the start/end dates in a separate table, say, candidate_dates , with columns like candidate_id, start, end. This has a so-called "one-to-many relationship" to the parent table, candidates .

Now, you can write a simple query which JOINs the two tables to get the answers you need.

Entity like that ?Entity like that ? One candidate can have one or more available dates and one available dates can only be linked to one candidate.

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Table(name="candidate_available_dates", uniqueConstraints={
 *    @ORM\UniqueConstraint(name="unique_candidate_available_dates", columns={"candidate_id", "start", "end"})
 * })
 *
 * @ORM\Entity(repositoryClass="App\Repository\CandidateAvailableDatesRepository")
 */
class CandidateAvailableDates
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Candidate", inversedBy="candidateAvailableDates")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="candidate_id", referencedColumnName="candidate_id", nullable=false)
     * })
     */
    private $candidate;

    /**
     * @ORM\Column(type="date")
     * @Assert\NotBlank
     */
    private $start;

    /**
     * @ORM\Column(type="date")
     * @Assert\NotBlank
     */
    private $end;

[...]
// GETTER and SETTER

And in Candidate entity, the reversed side

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\CandidateAvailableDates", mappedBy="candidate")
     */
    private $candidateAvailableDates;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM