prisma / prisma

Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB
https://www.prisma.io
Apache License 2.0
39.55k stars 1.54k forks source link

Json filtering `array_contains` doesn't match string partially in string array. #18621

Closed cody-ta closed 2 months ago

cody-ta commented 1 year ago

Bug description

JSON data example:

{
    "status": "ready",
    "data": ["This is a string", "Another string"]
}

Using string_contains:

where: {
    json_field: {
        path: ["status"],
        string_contains: "ead", // this what "contains" means.
    },
},

✅ match.

Using array_contains:

where: {
    json_field: {
        path: ["data"],
        array_contains: ["This is a string"],  // this should be array_equals
    },
},

✅ match.

where: {
    json_field: {
        path: ["data"],
        array_contains: ["Another string"],  // this should be array_equals
    },
},

✅ match.

but

where: {
    json_field: {
        path: ["data"],
        array_contains: [" string"],  // doesn't even the entry in string array contains "string"
    },
},

🚫 doesn't match anything.

How to reproduce

Use query like shown.

Expected behavior

prisma.document_files.findFirst({
    where: {
        json_field: {
            path: ["data"],
            array_contains: [" string"], // doesn't even the entry in string array contains "string"
        },
    },
});

Prisma information

model document_files {
  json_field Json?           @db.Json
}
prisma.document_files.findFirst({
    where: {
        json_field: {
            path: ["data"],
            array_contains: "string", // 
        },
    },
});

Environment & setup

Prisma Version

v4.12.0
alvis commented 1 year ago

I disagree that array_contains: "string" should return any match. array_contains implies an exact equal, so the current implementation is right.

However, I'd argue the following should return a match

prisma.document_files.findFirst({
  where: {
    json_field: {
      path: ["data"],
      string_contains: "string",
    },
  },
});
Weakky commented 2 months ago

Hey @cody-ta and @alvis, this is expected behavior. Even what you posted @alvis is not expected to work by design. Your path points to an array but you use the string_* operators. This will yield nothing. If anything, this issue should be converted to a feature request. If you still need this feature, please open another issue. For now though, I'm closing this one. Thanks for the report anyway 🙏