1

I'm trying to compare vespa query capabilities with both ES and MongoDb but I'm having a hard time to figure out what kind of support the YQL has for advanced queries over JSON. (by the way, this would be an awesome post for vespa blog)

For example given an object Person (see example below) with nested documents and/or an array of objects, how could do:

  • Select all Persons whose hobbies contains 'sport'.
  • Select all Persons whose Phones area code equals 'NY'.
  • Select all Persons whose Mother's Birthdate is greater than 1960.

Person = { Name: 'Joe', Hobbies: ['sports','books','bonzais'], Phones: [{Number: '12-3456-7890', areaCode: 'NY'},{Number: '22-3456-7890', areaCode: 'CA'}], Mother: { Name: 'Mom', Birthdate: '1961-24-02' } }

Also, are there any best practices regarding how should I model an object for Vespa/YQL?

Thanks in advance.

epc
  • 194
  • 4
  • 12

1 Answers1

4

A clarification first: YQL is just a query syntax. The JSON query language (https://docs.vespa.ai/documentation/reference/select-reference.html) is another. Yet another way (the most common) is to construct queries directly from the data received from clients in a Searcher (Java) component.

Below I show to construct your three examples in each of these variants. Vespa does not have a date type so here I've assumed you have a 'Birthyear' integer field instead.

Select all Persons whose hobbies contains 'sport'.

// YQL (as GET URL parameters)
?query=select * from Persons where hobbies contains 'sports';&type=yql

// JSON (POST body)
{ "contains" : [ "hobbies", "sports" ]}

// Java code
query.getModel().getQueryTree().setRoot(new WordItem("sports", "hobbies"));

Select all Persons whose Phones area code equals 'NY'.

// YQL (as GET URL parameters)
?query=select * from Persons where phones.areaCode contains 'NY';&type=yql

// JSON (POST body)
{"select" : { "where" : { "contains" : [ "phones.areaCode", "NY" ] } } }

// Java code
query.getModel().getQueryTree().setRoot(new WordItem("NY", "phones.areaCode"));

Select all Persons whose Mother's Birthdate is greater than 1960.

// YQL (as GET URL parameters)
?query=select * from Persons where mother.Birthyear > 1960;&type=yql

// JSON (POST body)
{"select" : { "where" : { "range" : [ "mother.Birthyear", { ">": 1960}] } } }

// Java code
query.getModel().getQueryTree().setRoot(new IntItem(">1960", "mother.Birthyear"));

Note:

  • Structured fields are referenced by dotting into the structures.
  • Containers becomes (has these tokens) or (equals) depending on the field matching setting.
Jon
  • 2,043
  • 11
  • 9
  • 1
    Great answer! See also the sameElement() (https://docs.vespa.ai/documentation/query-language.html) when searching multi-valued fields holding custom struct types. e.g map. – Jo Kristian Bergum Dec 03 '18 at 09:33