Taking inspiration from Lucene, you could start with an inverted index structure on disk, and then step a leapfrog iterator across all fields in question.
E.g.
Sample Docs
{"id": 1, "network": "NBC", "show": "Wheel of Fortune", "host": "Pat Sajak", "sponsor": "NordicTrack"}
{"id": 2, "network": "NBC", "show": "Jeopardy", "host": "Alex Trebek", "sponsor": "IBM Watson"}
{"id": 3, "network": "NBC", "show": "The Wizard of Odds", "host": "Alex Trebek", "sponsor": "NordicTrack"}
Inverted indices
network := "NBC" (1,2,3)
show := "Jeopardy" (2), "The Wizard of Odds" (3), "Wheel of Fortune" (1)
host := "Alex Trebek" (2,3), "Pat Sajak" (1)
sponsor := "IBM Watson" (2), "NordicTrack" (1,3),
Query issued for:
Network: NBC
Host: Alex Trebek
Sponsor: NordicTrack
Show: Unknown
Query execution
Iteration Step 1
network := "NBC" (1...
Iteration Step 2
network := "NBC" (1...
host := "Alex Trebek" (2...
Fault: id:2
is higher than consensus id ,
Iteration Step 3
network := "NBC" (1, 2...
host := "Alex Trebek" (2...
sponsor := "NordicTrack" (1, 3)
Fault: id:3
is higher than consensus id,
Iteration Step 4
network := "NBC" (1, 2, 3)
host := "Alex Trebek" (2, 3)
sponsor := "NordicTrack" (1, 3)
Match: All queried fields concur,
...
With linear iteration, the number of comparisons performed by leapfrog is the sum of the length of the postings lists for all fields queried.
But the number of comparisons can be reduced using Skip Lists. (Though this requires fast random access to postings).