Sort on missing value with pagination


(n3wtron) #1

Hi,
I have this situation:
Category --> Attributes
Category --> Documents
Document -(value)-> Attribute

I would like to get the documents of a specific category ordered by document attribute value and paginated.

This is the mutation:

{
  set{
    _:cat1 <dgraph.type> "Category" .
    _:cat1 <name> "cat1" .
    _:attr1 <dgraph.type> "Attribute" .
    _:attr1 <name> "attr1" .
    _:attr2 <dgraph.type> "Attribute" .
    _:attr2 <name> "attr2" .
    _:cat1 <attributes> _:attr1 .
    _:cat1 <attributes> _:attr2 .
    
    _:doc1 <dgraph.type> "Document" .
    _:doc1 <name> "doc1" .
    _:doc2 <dgraph.type> "Document" .
    _:doc2 <name> "doc2" .
    _:doc3 <dgraph.type> "Document" .
    _:doc3 <name> "doc3" .
    
    _:doc1 <attributes> _:attr1 (value="val1.1") .
    _:doc2 <attributes> _:attr1 (value="val1.2") .
    
    _:cat1 <documents> _:doc1 .
    _:cat1 <documents> _:doc2 .
    _:cat1 <documents> _:doc3 .
  }
}

For example I would like to have the documents of category cat1 ordered by attr1 asc paginated.
So the result should be: doc1,doc2,doc3.
Note that doc3 doesn’t have a relation with attr1, it’s only contained on the cat1.

Thank you for your help and time


(Michel Conrado) #2

I really didn’t get it. I can’t see where is the issue with pagination. Do you mind sharing a query that reproduces this?

{
  q(func: type(Category)) @filter(eq(name, "cat1"))@cascade {
    name
    # attributes {
    #   name
    # }
    documents {
      name
      attributes {
      name
    }
    }
  }
}

Result

{
  "data": {
    "q": [
      {
        "name": "cat1",
        "documents": [
          {
            "name": "doc1",
            "attributes": [
              {
                "name": "attr1"
              }
            ]
          },
          {
            "name": "doc2",
            "attributes": [
              {
                "name": "attr1"
              }
            ]
          }
        ]
      }
    ]
  }
}

(n3wtron) #3

Hi Michel, probably I wasn’t clear describing what I would like to have.
I would like to retrieve the documents( all 3 docs) associated to the category ordered by a specific attribute value and then paginate the result.

Thank you


(Michel Conrado) #4

Like this?

{
	var(func: type(Category)) @filter(eq(name, "cat1")) {
    documents {
      attributes  {
        ~attributes @facets(a as value) {
          name
        }
      }
    }
	}
  documents(func: uid(a), orderdesc: val(a))  {
    name
    val(a)
  }
}

Result

{
  "data": {
    "documents": [
      {
        "name": "doc2",
        "val(a)": "val1.2"
      },
      {
        "name": "doc1",
        "val(a)": "val1.1"
      }
    ]
  }
}

(n3wtron) #5

Hi Michel,
first of all thank you for the answer.
As you see the result doesn’t include the “doc3”.
To give you an example, imagine to have an e-commerce category like “cameras” that has some attribute like “megapixels” and “color”.
I would like to get all products contained in the category ordered by a category attribute (“megapixel”).
I know how I can do it, but I don’t know how I can show a product that is in the category that DOESN’T have a value for a specific attribute (i.e. color).
I’ve tried something like: retrieve products with the specific attribute “UNION” with the products that don’t have the attribute, but in this case I don’t know how I can paginate the results.

Below my try:

Mutation:

{
  set{
    _:cat1 <dgraph.type> "Category" .
    _:cat1 <name> "cat1" .
    _:attr1 <dgraph.type> "Attribute" .
    _:attr1 <name> "attr1" .
    _:attr2 <dgraph.type> "Attribute" .
    _:attr2 <name> "attr2" .
    _:cat1 <attributes> _:attr1 .
    _:cat1 <attributes> _:attr2 .
    
    _:prod1 <dgraph.type> "Product" .
    _:prod1 <name> "prod1" .
    _:prod2 <dgraph.type> "Product" .
    _:prod2 <name> "prod2" .
    _:prod3 <dgraph.type> "Product" .
    _:prod3 <name> "prod3" .
    
    _:prod1 <attributes> _:attr1 (value="val1.1") .
    _:prod2 <attributes> _:attr1 (value="val1.2") .
    
    _:cat1 <products> _:prod1 .
    _:cat1 <products> _:prod2 .
    _:cat1 <products> _:prod3 .
  }
}

**Query **

{
  q(func:eq(name,"cat1")){
    uid
    with_attr_prod: attributes@filter(eq(name,"attr1")){
      uid
      name
      prods: ~attributes @filter(type("Product")) @facets (orderdesc:value){
      	name
    	}
    }
    withotu_attr_prod: attributes@filter(not eq(name,"attr1")){
      uid
      name
      prods: ~attributes @filter(type("Product")) (orderasc:name){
      	name
    	}
    }
  }
}

Result

 {
  "uid": "0x1",
  "with_attr_prod": [
    {
      "uid": "0x2",
      "name": "attr1",
      "prods": [
        {
          "name": "prod1",
          "prods|value": "val1.1"
        },
        {
          "name": "prod2",
          "prods|value": "val1.2"
        }
      ]
    }
  ],
  "without_attr_prod": [
    {
      "uid": "0x3",
      "name": "attr2"
    }
  ]
}

Thank you


(Michel Conrado) #6

You can include it later. In my query I did take into account the values in facets that you used and what you said in your text.

I’ll take a look tomorrow in this last text.