如何从couchbase查询深层嵌套的json数组?

问题描述 投票:2回答:2

如何从couchbase查询深层嵌套的json数组?我在couchbase桶中有以下文件。我需要查询列出所有权限为“android.permission.BATTERY_STATS”的应用程序

如何查询列出具有嵌套json数组权限的所有应用程序?

我的Json文件,

文件:1

{
  "data": {
    "com.facebook.katana": {
      "studioId": "Facebook",
      "screenshotUrls": [
        "https://lh3.googleusercontent.com/JcPdPqplBxgG6dEQuxvuhO4jvE64AzxOCGWe8w55dMMeXU4rZs2MwpfGQTWvv6QR-g",
        "https://lh3.googleusercontent.com/w0kSYY7jlPjGDd3KEVgDTpzUf4k67G7rfELOf6qj1SSC7n6Ege44vp8QkeX57ZM6bFU"
      ],
      "primaryCategoryName": "Social",
      "studioName": "Facebook",
      "description": "Keeping up with friends is faster and easier than ever. Share updates and photos, engage with friends and Pages, and stay connected to communities important to you"
      "starRatings": {
        "1": 9706642,
        "2": 3384344,
        "3": 7224416,
        "4": 12323358,
        "5": 49438051
      },
      "numDownloads": "1,000,000,000+ downloads",
      "price": 0,
      "permissions": [
        "android.permission.ACCESS_COARSE_LOCATION",
        "android.permission.ACCESS_FINE_LOCATION",
        "android.permission.ACCESS_NETWORK_STATE",
        "android.permission.ACCESS_WIFI_STATE",
        "android.permission.AUTHENTICATE_ACCOUNTS",
        "android.permission.BATTERY_STATS",
        "android.permission.BLUETOOTH",
        "android.permission.READ_PHONE_STATE",
        "android.permission.READ_PROFILE",
        "android.permission.READ_SMS",
        "android.permission.READ_SYNC_SETTINGS",
        "com.nokia.pushnotifications.permission.RECEIVE",
        "com.sec.android.provider.badge.permission.READ",
        "com.sec.android.provider.badge.permission.WRITE",
        "com.sonyericsson.home.permission.BROADCAST_BADGE"
      ],
      "appId": "com.facebook.katana",
      "userRatingCount": 82076811,
      "currency": "USD",
      "iconUrl": "https://lh3.googleusercontent.com/ZZPdzvlpK9r_Df9C3M7j1rNRi7hhHRvPhlklJ3lfi5jk86Jd1s0Y5wcQ1QgbVaAP5Q=w100",
      "releaseDate": "Nov 14, 2018",
      "appName": "Facebook",
      "studioUrl": "https://www.facebook.com/facebook",
      "hasInAppPurchases": 1,
      "bundleId": "com.facebook.katana",
      "version": "198.0.0.53.101",
      "commentCount": 22211936,
      "fileSizeBytes": 58044343,
      "formattedPrice": "",
      "categoryIds": [
        "APPLICATION",
        "SOCIAL"
      ],
      "tagline": "Find friends, watch live videos, play games & save photos in your social network",
      "averageUserRating": 4.0770621299744,
      "primaryCategoryId": "SOCIAL",
      "videoScreenUrl": "https://lh4.ggpht.com/3RG_Y8JPK0Hcyui9OcapiONP_aDWKTRZ50wqZW_wbyOF0FamAYEYZfMTW9Cs1OT1kA"
    }
  },
  "response_msec": 11,
  "status": 200
}

文件:2

{
    "data": {
    "com.whatsapp": {
      "studioId": "WhatsApp Inc.",
      "screenshotUrls": [
        "https://lh3.googleusercontent.com/MMue08byixTw74ST_VkNQDUUJBgVEbjNHDYLhIuHmYhMIMJIp3KjVlnhhqZQOZUtNt8",
        "https://lh3.googleusercontent.com/foFmwvVGIwWWXJIukN7png18lFjFgbw3K7BqIm8G-jsFgSTVtkCa-dDkFApUzbvzIvbe"
      ],
      "primaryCategoryName": "Communication",
      "studioName": "WhatsApp Inc.",
      "description": "WhatsApp Messenger is a FREE messaging app available for Android and other smartphones.
      "starRatings": {
        "1": 4713598,
        "2": 1917919,
        "3": 4962745,
        "4": 11307648,
        "5": 55392894
      },
      "numDownloads": "1,000,000,000+ downloads",
      "price": 0,
      "permissions": [
        "android.permission.ACCESS_COARSE_LOCATION",
        "android.permission.ACCESS_FINE_LOCATION",
        "android.permission.ACCESS_NETWORK_STATE",
        "android.permission.ACCESS_WIFI_STATE",
        "android.permission.AUTHENTICATE_ACCOUNTS",
        "android.permission.BLUETOOTH",
        "android.permission.BROADCAST_STICKY",
        "android.permission.CAMERA",
        "android.permission.CHANGE_WIFI_STATE",
        "android.permission.GET_ACCOUNTS",
        "android.permission.GET_TASKS",
        "android.permission.INSTALL_SHORTCUT",
        "android.permission.INTERNET",
        "android.permission.MANAGE_ACCOUNTS",
        "com.whatsapp.permission.REGISTRATION",
        "com.whatsapp.permission.VOIP_CALL",
        "com.whatsapp.sticker.READ"
      ],
      "appId": "com.whatsapp",
      "userRatingCount": 78294804,
      "currency": "USD",
      "iconUrl": "https://lh6.ggpht.com/mp86vbELnqLi2FzvhiKdPX31_oiTRLNyeK8x4IIrbF5eD1D5RdnVwjQP0hwMNR_JdA=w100",
      "releaseDate": "Nov 5, 2018",
      "appName": "WhatsApp Messenger",
      "studioUrl": "http://www.whatsapp.com/",
      "bundleId": "com.whatsapp",
      "version": "2.18.341",
      "commentCount": 19763316,
      "fileSizeBytes": 23857699,
      "formattedPrice": "",
      "categoryIds": [
        "APPLICATION",
        "COMMUNICATION"
      ],
      "tagline": "Simple. Personal. Secure.",
      "averageUserRating": 4.4145045280457,
      "primaryCategoryId": "COMMUNICATION",
      "videoScreenUrl": "https://lh3.ggpht.com/aZrXAunkovhf0630Ykz1A7h2rzFX_dErd6fRiB7fNKU_DkNtetTquEra1bjc3sR2kLs"
    }
  },
  "response_msec": 15,
  "status": 200
}
json nested couchbase n1ql
2个回答
1
投票

正如我在评论中所说,这是一个棘手的问题。我将首先尝试简化您的文档,然后给出我想出的答案。

您有两个文档,其中包含具有权限数组的嵌套对象。每个嵌套对象都有一个(可能)不同的名称。所以,我们假设我们有两个这样简单的文档:

id: doc1
{
  "foo": {
    "permissions": [
      "android.permission.ACCESS_COARSE_LOCATION",
      "android.permission.BATTERY_STATS"
    ]
  }
}

id: doc2
{
  "bar": {
    "permissions": [
      "android.permission.ACCESS_FINE_LOCATION"
    ]
  }
}

第一个具有“foo”嵌套对象,第二个具有“bar”嵌套对象,但两个嵌套对象都具有“权限”数组。您想要查找具有“android.permission.BATTERY_STATS”权限的所有文档。

我查看了N1QL文档中可能有用的任何内容,我特别检查了Object Functions部分。有一个名为OBJECT_UNWRAP的功能可以解决这个问题。从文档:“此功能使您能够在不知道名称 - 值对中的名称的情况下解包对象。”

所以,如果我只是打开上面的文件,那么我基本上可以丢弃“foo”和“bar”部分。

SELECT META(b).id, OBJECT_UNWRAP(b).permissions
FROM sstbucket b

如果需要,你可以打开一个更深层次的嵌套对象,但我试图保持这个简单。

该查询的结果将是:

[
  {
    "id": "doc1",
    "permissions": [
      "android.permission.ACCESS_COARSE_LOCATION",
      "android.permission.BATTERY_STATS"
    ]
  },
  {
    "id": "doc2",
    "permissions": [
      "android.permission.ACCESS_FINE_LOCATION"
    ]
  }
]

现在,找到该文件是一个简单的ANY/SATISFIES声明:

SELECT META(b).id
FROM sstbucket b
WHERE ANY p IN OBJECT_UNWRAP(b).permissions SATISFIES p == 'android.permission.BATTERY_STATS' END;

哪会回来

[
  {
    "id": "doc1"
  }
]

所以,这是有效的。我不确定的是如何为此特定查询创建正确的索引。我创建了一个主要索引,以使其工作(CREATE PRIMARY INDEX ON sstbucket),但这不会很好。


1
投票

您可以使用OBJECT函数(https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/objectfun.html)和数组索引。

如果您需要文档ID或整个文档。

CREATE INDEX ix1 ON default ( DISTINCT ARRAY  (DISTINCT ARRAY permision
                                               FOR permision IN app.permissions END)
                                       FOR app IN OBJECT_VALUES(data) END);
SELECT META(d).id FROM default AS d
WHERE ANY app IN OBJECT_VALUES(d.data)
      SATISFIES (ANY permision IN app.permissions
                 SATISFIES permision = "android.permission.BATTERY_STATS"
                 END)
      END;

如果您只需要appId并查看它是否使用覆盖索引。

CREATE INDEX ix2 ON default ( ALL ARRAY  (ALL ARRAY [permision, app.appId]
                                               FOR permision IN app.permissions END)
                                       FOR app IN OBJECT_VALUES(data) END);

SELECT [permision, app.appId][1] AS appId  FROM default AS d
UNNEST OBJECT_VALUES(d.data) AS app
UNNEST app.permissions AS permision
WWHERE [permision, app.appId] >= ["android.permission.BATTERY_STATS"] AND
        [permision, app.appId] < [SUCCESSOR("android.permission.BATTERY_STATS")] ;
© www.soinside.com 2019 - 2024. All rights reserved.