【问题标题】:Parse Query by subfield/dot notation按子字段/点符号解析查询
【发布时间】:2017-10-28 15:27:45
【问题描述】:

tl;博士

ParseCloud/MongoDB 可以按Pointer<class>.filed 过滤吗?经过 Pointer<class>.Pointer<class> ?是否存在该文件中的数据?

长问题:

Round是对象,到时候会自动播放。

Payment 表示用户已付款的对象。付款时,我们将字段 round 设置为它。

Player 在线链接UserPayment

我需要查询播放器几个条件:

  1. Player

    • 在线
    • 有效(没有roundvalid 等于'有效')payment
  2. Player

    • user 等于特定用户
    • 没有payment
  3. Player

    • user 等于特定用户
    • 有有效(没有roundvalid等于'有效')付款

除了验证Payment inside Player 查询之外,我让一切正常工作。

这是列表中的条件 1

var query = new Parse.Query(keys.Player);  
query.skip(0);
query.limit(oneRoundMaxPlayers);
query.greaterThanOrEqualTo(keys.last_online_date, lastAllowedOnline);

// looks like no filter applied here
query.doesNotExist("payment.round"); 

query.exists(keys.payment);

// This line will make query return 0 elements 
// query.equalTo("payment.valid", "valid"); 

query.include(keys.user);
query.include(keys.payment);

这里是2 OR 3

var queryPaymentExists = new Parse.Query(keys.Player);  
queryPaymentExists.skip(0);
queryPaymentExists.limit(1);
queryPaymentExists.exists(keys.payment);

//This line not filtering
queryPaymentExists.doesNotExist(keys.payment + "." + keys.round); 

queryPaymentExists.equalTo(keys.user, user);

// This line makes query always return 0 elements
// queryPaymentExists.equalTo(keys.payment + "." + keys.valid, keys.payment_valid);

var queryPaymentDoesNotExist = new Parse.Query(keys.Player);  
queryPaymentDoesNotExist.skip(0);
queryPaymentDoesNotExist.limit(1);
queryPaymentDoesNotExist.doesNotExist(keys.payment);
queryPaymentDoesNotExist.equalTo(keys.user, user);

var compoundQuery = Parse.Query.or(queryPaymentExists, queryPaymentDoesNotExist);
compoundQuery.include(keys.user);
compoundQuery.include(keys.payment);
compoundQuery.include(keys.payment + "." + keys.round);

我检查了来自 Mongo 的日志,它们看起来如下

    verbose: REQUEST for [GET] /classes/Player: {
  "include": "user,payment,payment.round",
  "where": {
    "$or": [
      {
        "payment": {
          "$exists": true
        },
        "payment.round": {
          "$exists": false
        },
        "user": {
          "__type": "Pointer",
          "className": "_User",
          "objectId": "ASPKs6UVwb"
        }
      },
      {
        "payment": {
          "$exists": false
        },
        "user": {
          "__type": "Pointer",
          "className": "_User",
          "objectId": "ASPKs6UVwb"
        }
      }
    ]
  }
}

回复如下:

verbose: RESPONSE from [GET] /classes/Player: {
  "response": {
    "results": [
      {
        "objectId": "VHU9uwmLA7",
        "last_online_date": {
          "__type": "Date",
          "iso": "2017-10-28T15:15:23.547Z"
        },
        "user": {
          "objectId": "ASPKs6UVwb",
          "username": "cn92Ekv5WPJcuHjkmTajmZMDW",

          },
          "createdAt": "2017-10-22T11:43:16.804Z",
          "updatedAt": "2017-10-25T09:23:20.035Z",


          "ACL": {
            "*": {
              "read": true
            },
            "ASPKs6UVwb": {
              "read": true,
              "write": true
            }
          },
          "__type": "Object",
          "className": "_User"
        },
        "createdAt": "2017-10-27T21:03:35.442Z",
        "updatedAt": "2017-10-28T15:15:23.556Z",
        "payment": {
          "objectId": "nr7ln7U3eJ",
          "payment_date": {
            "__type": "Date",
            "iso": "2017-10-27T23:42:50.614Z"
          },
          "user": {
            "__type": "Pointer",
            "className": "_User",
            "objectId": "ASPKs6UVwb"
          },
          "createdAt": "2017-10-27T23:42:50.624Z",
          "updatedAt": "2017-10-28T15:12:30.131Z",
          "valid": "valid",
          "round": {
            "objectId": "jF9gqG4ndh",
            "round_date": {
              "__type": "Date",
              "iso": "2017-10-28T15:12:00.027Z"
            },
            "createdAt": "2017-10-28T15:11:00.036Z",
            "updatedAt": "2017-10-28T15:12:30.108Z",
            ,
            "ACL": {
              "*": {
                "read": true
              }
            },
            "__type": "Object",
            "className": "Round"
          },
          "ACL": {
            "ASPKs6UVwb": {
              "read": true
            }
          },
          "__type": "Object",
          "className": "Payment"
        },
        "ACL": {
          "ASPKs6UVwb": {
            "read": true
          }
        }
      }
    ]
  }
}

您可以看到响应包含 payment.round。

我的问题如下:

  1. ParseCloud/MongoDB 可以按Pointer<class>.filed 过滤吗?通过Pointer<class>.Pointer<class>?是否存在该文件中的数据?
  2. 如果User 可以有可能PlayersUser 可以有很多Payments,我该如何解决这种情况。

UPD 据我发现 mongo 应该支持通过“点符号”过滤 mongodb query by sub-field 那我做错了什么?

【问题讨论】:

    标签: parse-platform parse-server


    【解决方案1】:

    简答:

    1. 没有
    2. 简化您的数据结构

    长答案:

    点符号可用于

    • include 指针文档,就像您在代码中所做的那样,例如include(keys.user)
    • filter 用于字段的属性,例如{properyA: 1, propertyB: 2}。所有数据都在字段中,而不是在 Parse 指针引用的另一个集合中的另一个文档中。

    点表示法不能用作 Parse 查询中引用指针的过滤参数。 MongoDB 也不支持这样的过滤,pointer 的概念是 Parse 的概念,而不是 MongoDB 的概念。在像 MongoDB 这样的 NoSQL 环境中,在查询语言中使用的表之间没有关系,因为它不像 SQL 数据库那样是“关系数据库”。然而,Parse 为简单的查询提供了一些舒适的 SQL,其概念为 pointercompoundQuerymatchesKeyInQuery

    如果在您的情况下这还不够,只需将字段添加到集合中即可。代价是您可能在多个集合中拥有相同的字段和数据,但具有更快的查询执行时间的优势。

    找到正确的数据结构是 NoSQL 的一大主题,因为没有通用的正确结构。集合和文档结构基本上是在以下方面进行权衡设计的:

    • 执行性能
    • 查询必要性/频率
    • 安全性(访问级别)
    • 和数据存储大小

    它们是流动的,会随着时间而改变。随着您的应用及其查询发生变异,如果长期收益大于一次性工作量,您还需要更改数据结构。

    【讨论】:

      猜你喜欢
      • 2013-03-15
      • 2019-05-03
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2019-03-31
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多