如何在Couchbase查询中按JSON对象的值对文档进行排序?

huangapple go评论61阅读模式
英文:

How to sort documents by value of json object in couchbase query?

问题

我有以下类型的数据存储在名为"persons"的集合中,我正在使用spring-data-couchbase在Java POJO中读取这些数据,并在我的PersonsRepository类中使用@Query注解编写SQL查询以根据需要获取数据。

  ########## 文档 1
  {
    "person": [
      {
        "id": "name",
        "value": "abc"
      },
      {
        "id": "age",
        "value": 40
      },
      {
        "id": "country",
        "value": "usa"
      }
    ],
    "loggedOn": "2020-07-14"
  }
  ########## 文档 2
  {
    "person": [
      {
        "id": "name",
        "value": "def"
      },
      {
        "id": "age",
        "value": 32
      },
      {
        "id": "country",
        "value": "uk"
      }
    ],
    "loggedOn": "2020-08-10"
  }

现在,我需要在Couchbase中编写SQL,以便通过提供"person"属性的值对这些文档进行排序和分页。

即按姓名排序或按年龄排序

注意:我不想在我的Java POJO中下载数据,然后进行排序和分页,因为这需要大量的网络带宽和I/O,由于数据集很大。

英文:

I have the below kind of data stored in my collection called persons, I am using spring-data-couchbase for reading this data in Java POJOs, and I am using the @Query annotation in my PersonsRepository class and writing SQL query for fetching data according to my need.

  ########## Document 1
  {
    "person": [
      {
        "id": "name",
        "value": "abc"
      },
      {
        "id": "age",
        "value": 40
      },
      {
        "id": "country",
        "value": "usa"
      }
    ],
    "loggedOn": "2020-07-14"
  }
  ########## Document 2
  {
    "person": [
      {
        "id": "name",
        "value": "def"
      },
      {
        "id": "age",
        "value": 32
      },
      {
        "id": "country",
        "value": "uk"
      }
    ],
    "loggedOn": "2020-08-10"
  }

Now I need to write SQL in Couchbase such that I can sort and paginate these documents by providing a value of person's attribute.

I.e. sort by name or sort by age

Note: I do not want to download data in my Java POJO and then do sorting and paging, as it requires huge network bandwidth and I/O due to a large dataset.

答案1

得分: 2

Option 1) 使用UNNEST对数组进行排序,根据数组元素进行筛选和排序:

SELECT p.id, p.`value`
FROM default AS d
UNNEST d.person AS p
WHERE p.id = "age" AND p.`value` > 30
ORDER BY p.`value`
OFFSET 10
LIMIT 5;

Pre CB 7.1

CREATE INDEX ix1 ON default (ALL ARRAY p.id FOR p IN person END);

CB 7.1+

CREATE INDEX ix1 ON default (ALL ARRAY FLATTEN_KEYS(p.id, p.`value`) FOR p IN person END);

Option 2) 找到您感兴趣的数组元素并根据该元素进行排序(使用主索引):

SELECT d.*
FROM default AS d
LET pObj = FIRST p FOR p IN person WHEN p.id = "age" END
WHERE pObj IS NOT NULL
ORDER BY pObj.`value`
OFFSET 10
LIMIT 5;

Option 3) 更改数据模型,不使用数组,而是使用对象(如果属性是唯一的),在需要时使用对象函数:https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/objectfun.html

{
"name": "def",
"age": 32,
"country": "uk",
"loggedOn": "2020-08-10"
}

SELECT d.*
FROM default AS d
WHERE p.age > 30
ORDER BY p.age
OFFSET 10
LIMIT 5;
英文:

To sort the values from ARRAY you need ARRAY position and which can vary in your case from document.
You have following options:

Option 1) UNNEST the ARRAY, filter out and do sort based on ARRAY elements

SELECT p.id, p.`value`
FROM default AS d
UNNEST d.person AS p
WHERE p.id = "age" AND p.`value` > 30
ORDER BY p.`value`
OFFSET 10
LIMIT 5;

Pre CB 7.1

 CREATE INDEX ix1 ON default (ALL ARRAY p.id FOR p IN person END);

CB 7.1+

 CREATE INDEX ix1 ON default (ALL ARRAY FLATTEN_KEYS(p.id, p.`value`) FOR p IN person END);

Option 2) Find the ARRAY element you are interested and Sort based on that (USE primary index)

SELECT d.*
FROM default AS d
LET pObj = FIRST p FOR p IN person WHEN p.id = "age" END
WHERE  pObj IS NOT NULL
ORDER BY pObj.`value`
OFFSET 10
LIMIT 5;

Option 3) Change the data model instead of ARRAY use as Object like below (if attributes are unique) and when required use OBJECT functions https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/objectfun.html

{
"name":"def",
"age": 32,
"country": "uk",
"loggedOn": "2020-08-10"
}

SELECT d.*
FROM default AS d
WHERE  p.age > 30
ORDER BY p.age
OFFSET 10
LIMIT 5;

huangapple
  • 本文由 发表于 2023年6月26日 13:04:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76553642.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定