Как выполнить левое соединение в базе данных Azure Cosmos с помощью API gremlin - PullRequest
0 голосов
/ 26 октября 2019

Я изучаю Gremlin API Azure Cosmos DB и пытаюсь перевести некоторые операторы SQL в обходы Gremlin.

Команды ниже:


//add product vertex
g.addV('product').property('id', 'product1')
g.addV('product').property('id', 'product2')
g.addV('product').property('id', 'product3')
g.addV('product').property('id', 'product4')
g.addV('product').property('id', 'product5')

//add product_category vertex
g.addV('product_category').property('id', 'category1')
g.addV('product_category').property('id', 'category2')

//connect product and product_categories

g.V('product1').addE('belongs_to').to(g.V('category1'))
g.V('product2').addE('belongs_to').to(g.V('category1'))
g.V('product3').addE('belongs_to').to(g.V('category2'))
g.V('product4').addE('belongs_to').to(g.V('category2'))
g.V('product5').addE('belongs_to').to(g.V('category2'))

//add image vertex
g.addV('image').property('public_url', 'url_1').property('id', 'image1')
g.addV('image').property('public_url', 'url_2').property('id', 'image2')


//link products to images

g.V('product1').addE('belongs_to').property('primary', true).to(g.V('image1'))
g.V('product2').addE('belongs_to').property('primary', true).to(g.V('image2'))

Теперь, как вы видите, не все продукты имеютimages.

Я хочу иметь возможность выбрать все товары с категорией и свойством изображения. Если у продукта нет изображения, его все равно следует выбрать с нулевым свойством изображения.

Я пытаюсь сделать что-то похожее на левое соединение, перейдя по этой ссылке: http://sql2gremlin.com/#_left_join

Но, к сожалению,Gremlin API Azure Cosmos пока не поддерживает шаг match ().

Мой текущий запрос выбирает только те продукты, которые имеют исходящий край изображения:

g.V()
.has('label', 'product')
.as('product')
.outE('has_image')
.has('primary', true)
.inV()
.as('primary_image')
.in('has_image')
.out('belongs_to')
.as('category')
.select('product','primary_image','category')
.by(__.valueMap()).by(__.values('public_url')).by(__.values('name'))

1 Ответ

1 голос
/ 28 октября 2019

Итак, здесь происходит пара вещей:

1) Вышеописанный скрипт не работал правильно для вставки данных в TinkerGraph (у меня нет учетной записи Cosmos). Я добавил обновленный скрипт ниже.

2) То, что вы пытаетесь сделать, не нуждается в левом соединении. Поскольку оба эти отношения относятся к продукту, вы можете просто спроецировать свои результаты из вершин продукта, как показано здесь:

g.V().
  hasLabel('product').
  project('product', 'category', 'image').
    by(id()).
    by(out('belongs_to').id()).
    by(
      __.out('has_image').fold().
      coalesce(
        unfold().id(), 
        constant('No Image')
      )
    )

Это работает, находя все вершины продукта и затем возвращая изображение и категорию

3) Операция coalesce основана на этом рецепте Gremlin для проверки существования элемента. Если он ничего не находит, потому что рецепт не существует, он возвращает постоянное значение

4) Gremlin не позволяет возвращать значения null, поэтому вам нужно что-то вернуть

Обновлен скрипт Add

//add product vertex
g.addV('product').property(id, 'product1')
g.addV('product').property(id, 'product2')
g.addV('product').property(id, 'product3')
g.addV('product').property(id, 'product4')
g.addV('product').property(id, 'product5')

//add product_category vertex
g.addV('product_category').property(id, 'category1')
g.addV('product_category').property(id, 'category2')

//connect product and product_categories

g.V('product1').addE('belongs_to').to(g.V('category1'))
g.V('product2').addE('belongs_to').to(g.V('category1'))
g.V('product3').addE('belongs_to').to(g.V('category2'))
g.V('product4').addE('belongs_to').to(g.V('category2'))
g.V('product5').addE('belongs_to').to(g.V('category2'))

//add image vertex
g.addV('image').property(id, 'image1').property('public_url', 'url_1')
g.addV('image').property(id, 'image2').property('public_url', 'url_2')


//link products to images

g.V('product1').addE('has_image').to(V('image1')).property('primary', true)
g.V('product2').addE('has_image').to(V('image2')).property('primary', true)
...