0

I'm trying to do a search for specific items within Core Data

I have an Entity Colour, which has a NSSet of ProjectColour Entities. The ProjectColour Entities have a field called project which is a Project Entity, and two int fields called fullLeft and partialLeft. This has a field called drillType which is a string.

I'm trying to all objects that have a drillType of Square and both fullLeft and partialLeft > 0

I've tried

if searchedText.lowercased() == "square" {
    let predicateNumbers = NSPredicate(format: "ANY projectColours.fullLeft > 0 OR ANY projectColours.partialLeft > 0")
    let predicateDrillType = NSPredicate(format: "ANY projectColours.project.drillType == 'Square'")

    fetchRequest.predicate = NSCompoundPredicate(type: .and, subpredicates: [predicateNumbers, predicateDrillType])
}

This works when searching for Round as the type but with squares, its returning the wrong objects i.e. Two objects, one which is a square but partial and full are equal to 0 The second is a Round which has partial equal to 1

Example 3 Colour Objects

  • 1
  • 2
  • 3

3 Project Colour Objects

  • 1st. Colour (linked to colour) = 1, Full = 1, Partial = 1, Project (linked to project entity) - Drill Type = Square
  • 2nd. Colour = 2, Full = 1, Partial = 1, Project (linked to project entity) - Drill Type = Round
  • 3rd. Colour (linked to colour) = 1, Full = 0, Partial = 0, Project (linked to project entity) - Drill Type = Square

When searching, I get for square, I get all 3 results return, even through the second Project Colour object is Round

When searching for text, I want all ProjectColour.project.drillType of Square and ProjectColour.fullLeft > 0 AND ProjectColour.partialLeft > 0

fetchRequest.predicate = NSPredicate(format: "ANY projectColours.project.drillType == 'Square'") - Works

fetchRequest.predicate = NSPredicate(format: "ANY projectColours.fullLeft > 0 OR ANY projectColours.partialLeft > 0") - Works

But when I try and combine the two it doesn't work

Ceri Turner
  • 830
  • 2
  • 12
  • 36
  • *“I'm trying to all objects that have a drillType of Square and both fullLeft and partialLeft > 0”* – that would be a list of ProjectColour objects, not Colour objects. – Martin R Jun 09 '19 at 17:16
  • I'm getting Colour objects. The default search without the searchText is to list all Colour objects, otherwise I'd only get Colours that have a ProjectColour objects, and not all will have. You can search for a colour number, or search for specific keywords – Ceri Turner Jun 09 '19 at 17:21

1 Answers1

1

Assuming that you want to search for all Colour objects which have some related ProjectColour object with the given project.drillType and positive fullLeft and positive partialLeft: You need a SUBQUERY for such a request. Something like (untested):

let pred = NSPredicate(format: """
    SUBQUERY(projectColours, $pc, $pc.fullLeft > 0
                                    AND $pc.partialLeft > 0
                                    AND $pc.project.drillType ==[c] %@
            ).@count > 0
""", searchedText)

Note also that keyword substitution with %@ is preferred over string literals inside the predicate format string, and that ==[c] can be used for case-insensitive string comparison (so that the search text does not need to be converted to lowercase)

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Getting no results at all with that. The lowercase is purely so that it doesn't matter what case the user searches for it picks it up, the actual values start with a capital. i.e. Square/sQuare,square all search for Square – Ceri Turner Jun 09 '19 at 17:36
  • @CeriTurner: Can you somehow show a sample data set (and the expected result list)? Perhaps I misunderstood your question. – Martin R Jun 09 '19 at 17:38
  • added some info in main post – Ceri Turner Jun 09 '19 at 17:45
  • @CeriTurner: So which objects do you want to fetch? There is no ProjectColour with a drillType of Square and both fullLeft and partialLeft > 0. – Martin R Jun 09 '19 at 17:48
  • When searching for text, I want all ProjectColour.project.drillType of Square and ProjectColour.fullLeft > 0 AND ProjectColour.partialLeft > 0 fetchRequest.predicate = NSPredicate(format: "ANY projectColours.project.drillType == 'Square'") - Works fetchRequest.predicate = NSPredicate(format: "ANY projectColours.fullLeft > 0 OR ANY projectColours.partialLeft > 0") - Works But when I try and combine the two it doesn't work – Ceri Turner Jun 09 '19 at 17:56
  • @CeriTurner: Let's try it like this: In your sample data set with colors 1, 2, 3: What would be the expected result, and why? – Martin R Jun 09 '19 at 17:57
  • I would expect to get 1. 1 is Square and have has either Full or Partial > 0. 2 Is round so should be return. 3 is Square, but doesn't have Full or Partial > 0 – Ceri Turner Jun 09 '19 at 18:01
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194665/discussion-between-martin-r-and-ceri-turner). – Martin R Jun 09 '19 at 18:03