4

I'm working on a query which will filter documents with nodes that are empty JSON arrays like this (Output property):

{
    "Id": "0aec6b50-03ff-48c9-ac35-1b5e7640a892", 
    "Input": "00000000-0000-0000-0000-000000000000", 
    "Output": [
    ]
}

for now I'm using this query:

cts.orQuery([
        cts.notQuery(cts.jsonPropertyValueQuery('Input','00000000-0000-0000-0000-000000000000')), 
            cts.jsonPropertyValueQuery('Output', '*', 'wildcarded')
    ])

It is filtering all documents with empty (empty GUID) Input field and should (but isn't) filter documents with empty (empty array) Output.

It is working with document:

{
    "Id": "0aec6b50-03ff-48c9-ac35-1b5e7640a892", 
    "Input": "00000000-0000-0000-0000-000000000000", 
    "Output": ""
}

I assume that it is because empty array is for MarkLogic a value. Has anyone had similar issue? How to query for empty JSON array?

EDIT:

non-empty message (which should be returned) looks like this:

{
    "Id": "0aec6b50-03ff-48c9-ac35-1b5e7640a892", 
    "Input": "00000000-0000-0000-0000-000000000000", 
    "Output": [
        "91ad81fe-9c82-4090-b6a9-a918f901de46"
    ]
}
Kamil Budziewski
  • 22,699
  • 14
  • 85
  • 105
  • I think it does not filter on empty output but on existence of output. It will match any property with the name Output. You can use JavaScript to filter the empty arrays out but that may be not to your liking depending on the size of the set. Maybe you can NOT search for all values you DO have in Output so the $value of jsonPropertyValueQuery takes the complete Output value lexicon :) – Thijs Sep 15 '15 at 23:02

1 Answers1

2

cts.jsonPropertyValueQuery('Output', '*', 'wildcarded') will match any Output property value that would translate to an empty string in the universal index. That means it matches:

  • Output: ""
  • Output: []
  • Output: [""]
  • and Output: null

Simplest way to find Output properties with (exclusively) non-empty values, you can combine the above with a negating search on empty string:

cts.andQuery([
  cts.jsonPropertyValueQuery('Output', '*', 'wildcarded'),
  cts.notQuery(
    cts.jsonPropertyValueQuery('Output', '')
  )
])

Note though that this will also exclude Output properties with an array of empty string and non-empty string values. To find Output properties with at least one non-empty string (so also mixtures of empty and non-empty values), you should apply a range index, and use:

cts.jsonPropertyRange('Output', '!=', '')

That will ignore null and empty array.

HTH!

grtjn
  • 20,254
  • 1
  • 24
  • 35