Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finding by items in JsonType #1359

Closed
tudddorrr opened this issue Jan 27, 2021 · 3 comments · Fixed by #1384
Closed

Finding by items in JsonType #1359

tudddorrr opened this issue Jan 27, 2021 · 3 comments · Fixed by #1384
Assignees
Labels
enhancement New feature or request

Comments

@tudddorrr
Copy link

tudddorrr commented Jan 27, 2021

Hey,

If you had a JsonType field that had this signature: customProps: { [key: string]: any }, is there a nice way to search for keys inside that object?

Currently to find a player with the specified customProps key I'm doing:

const player = await em.getRepository(Player).findOne({
  [expr(`json_extract(customProps, '$.${keyName}')`)]: id
})

Ideally I'd do something like this:

const player = await em.getRepository(Player).findOne({ customProps: { [keyName]: id } })

However that throws an error with the query helper:

TypeError: Cannot read property 'includes' of undefined
      at /node_modules/@mikro-orm/core/utils/QueryHelper.js:157:77
      at Array.reduce (<anonymous>)
      at Function.processCustomType (/node_modules/@mikro-orm/core/utils/QueryHelper.js:156:38)
      at /node_modules/@mikro-orm/core/utils/QueryHelper.js:92:37
      at Array.reduce (<anonymous>)
      at Function.processWhere (/node_modules/@mikro-orm/core/utils/QueryHelper.js:75:35)
      at SqlEntityManager.findOne (/node_modules/@mikro-orm/core/EntityManager.js:177:37)
      at SqlEntityRepository.findOne (/node_modules/@mikro-orm/core/entity/EntityRepository.js:36:24)
      at PlayersAPIService.<anonymous> (/src/services/api/players-api.service.ts:39:51)
      at Generator.next (<anonymous>)

Am I missing something or is there currently no way of finding by items inside a json column?

@B4nan
Copy link
Member

B4nan commented Jan 27, 2021

Currently the only way to do this is via embeddables in object mode, but we could support this for JSON columns too (as well as object properties in mongo).

https://mikro-orm.io/docs/embeddables/#storing-embeddables-as-objects

@B4nan B4nan added the enhancement New feature or request label Jan 27, 2021
@tudddorrr
Copy link
Author

tudddorrr commented Jan 27, 2021

Ah okay I see, that makes sense. My main problem is that customProps can have any key/value pairs in it so I can't make an embeddable out of it. I'll look into it, thanks!

@B4nan B4nan self-assigned this Feb 2, 2021
B4nan added a commit that referenced this issue Feb 2, 2021
We can query by JSON object properties easily:

```ts
const b = await em.findOne(Book, {
  meta: {
    valid: true,
    nested: {
      foo: '123',
      bar: 321,
      deep: {
        baz: 59,
        qux: false,
      },
    },
  },
});
```

Will produce following query (in postgres):

```sql
select "e0".*
from "book" as "e0"
where ("meta"->>'valid')::bool = true
  and "meta"->'nested'->>'foo' = '123'
  and ("meta"->'nested'->>'bar')::float8 = 321
  and ("meta"->'nested'->'deep'->>'baz')::float8 = 59
  and ("meta"->'nested'->'deep'->>'qux')::bool = false
limit 1
```

> All drivers are currently supported (including sqlite and mongo). In postgres we
> also try to cast the value if we detect number or boolean on the right-hand side.

Closes #1359
Related: #1261
B4nan added a commit that referenced this issue Feb 2, 2021
We can query by JSON object properties easily:

```ts
const b = await em.findOne(Book, {
  meta: {
    valid: true,
    nested: {
      foo: '123',
      bar: 321,
      deep: {
        baz: 59,
        qux: false,
      },
    },
  },
});
```

Will produce following query (in postgres):

```sql
select "e0".*
from "book" as "e0"
where ("meta"->>'valid')::bool = true
  and "meta"->'nested'->>'foo' = '123'
  and ("meta"->'nested'->>'bar')::float8 = 321
  and ("meta"->'nested'->'deep'->>'baz')::float8 = 59
  and ("meta"->'nested'->'deep'->>'qux')::bool = false
limit 1
```

> All drivers are currently supported (including sqlite and mongo). In postgres we
> also try to cast the value if we detect number or boolean on the right-hand side.

Closes #1359
Related: #1261
B4nan added a commit that referenced this issue Feb 2, 2021
We can query by JSON object properties easily:

```ts
const b = await em.findOne(Book, {
  meta: {
    valid: true,
    nested: {
      foo: '123',
      bar: 321,
      deep: {
        baz: 59,
        qux: false,
      },
    },
  },
});
```

Will produce following query (in postgres):

```sql
select "e0".*
from "book" as "e0"
where ("meta"->>'valid')::bool = true
  and "meta"->'nested'->>'foo' = '123'
  and ("meta"->'nested'->>'bar')::float8 = 321
  and ("meta"->'nested'->'deep'->>'baz')::float8 = 59
  and ("meta"->'nested'->'deep'->>'qux')::bool = false
limit 1
```

> All drivers are currently supported (including sqlite and mongo). In postgres we
> also try to cast the value if we detect number or boolean on the right-hand side.

Closes #1359
Related: #1261
B4nan added a commit that referenced this issue Feb 2, 2021
We can query by JSON object properties easily:

```ts
const b = await em.findOne(Book, {
  meta: {
    valid: true,
    nested: {
      foo: '123',
      bar: 321,
      deep: {
        baz: 59,
        qux: false,
      },
    },
  },
});
```

Will produce following query (in postgres):

```sql
select "e0".*
from "book" as "e0"
where ("meta"->>'valid')::bool = true
  and "meta"->'nested'->>'foo' = '123'
  and ("meta"->'nested'->>'bar')::float8 = 321
  and ("meta"->'nested'->'deep'->>'baz')::float8 = 59
  and ("meta"->'nested'->'deep'->>'qux')::bool = false
limit 1
```

> All drivers are currently supported (including sqlite and mongo). In postgres we
> also try to cast the value if we detect number or boolean on the right-hand side.

Closes #1359
Related: #1261
@tudddorrr
Copy link
Author

Thanks @B4nan !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants