【问题标题】:Indexes: Search by Boolean?索引:按布尔搜索?
【发布时间】:2021-07-08 23:07:12
【问题描述】:

我在使用 FaunaDB 索引时遇到了一些问题。 FQL 非常强大,但文档似乎(目前)仅限于几个示例/用例。 (按字符串搜索)

我有一个订单集合,其中包含几个字段:状态、ID、客户、材料和日期。

我的目标是根据订单的状态、打开或关闭(布尔真/假)搜索/过滤订单。

这是我创建的索引:

CreateIndex({
  name: "orders_all_by_open_asc",
  unique: false,
  serialized: true,
  source: Collection("orders"),
  terms: [{ field: ["data", "status"] }],
  values: [
    { field: ["data", "unique_id"] },
    { field: ["data", "client"] },
    { field: ["data", "material"] },
    { field: ["data", "date"] }
  ]
}

因此,对于这个索引,我想指定 TRUE 或 FALSE 并获取所有相应的订单,包括它们的数据(字段)。

我有两个问题:

  1. 当我使用 Javascript 驱动程序传递 TRUE 或 FALSE 时,没有返回任何内容 :( 是否可以通过布尔值进行搜索,或者仅通过字符串/数字进行搜索?

这是我的查询(在 FQL 中,使用 Shell):

Match(Index("orders_all_by_open_asc"), true)

不幸的是,没有返回任何内容。我可能做错了。

  1. 第二个(稍微不相关的)问题。当我创建一个索引并指定一堆值时,返回的数据似乎是数组格式,只有值,而不是字段。一个例子:
[
  1001,
  "client1",
  "concrete",
  "2021-04-13T00:00:00.000Z",
],
[
  1002,
  "client2",
  "wood",
  "2021-04-13T00:00:00.000Z",
]

这种格式对我不利,因为我的前端期望接收一个以字段为键、值作为属性的对象。示例:

data:
{
  unique_id : 1001,
  client : "client1",
  material : "concrete",
  date: "2021-04-13T00:00:00.000Z"
},
{
  unique_id : 1002,
  client : "client2",
  material : "wood",
  date: "2021-04-13T00:00:00.000Z"
},
etc..

在使用索引值时,有什么方法可以获取字段和值,还是总是返回一个数组(而不是对象)?

我可以为此使用 Lambda 或其他东西吗?

我确实有另一个使用 Map 和 Lambda 效果很好的查询,并返回整个文档,包括 Ref 和 Data 字段:

      Map(
        Paginate(
          Match(Index("orders_by_date"), date),
        ),
        Lambda('item', Get(Var('item')))
      )

这很好用,但不幸的是,它还为每个返回的文档执行一个 Get 请求,这似乎非常低效。

我要建立的这个新索引,按订单状态过滤,将用于返回数百个订单,每天数百次。所以我试图让它尽可能高效,但如果它只能返回一个数组,它就没有用了。

提前致谢!!索引很棒,但很难掌握,因此我们将不胜感激。

【问题讨论】:

    标签: faunadb


    【解决方案1】:

    另一个建议,也许我错了,并且在搜索文档时失败了,但无论如何我都会发布以防万一。

    我的索引未能返回对象,这里的示例数据是 client 字段:

      "data": {
        "status": "LIVRAISON",
        "open": true,
        "unique_id": 1001,
        "client": {
          "name": "TEST1",
          "contact_name": "Bob",
          "email": "bob@client.com",
          "phone": "555-555-5555"
        
    

    这里,client 字段返回为 null,即使它已在索引中指定。

    通过阅读文档,这里:https://docs.fauna.com/fauna/current/api/fql/indexes?lang=javascript#value

    Value Objects 部分,我能够理解对于对象,索引字段必须定义为一个数组,每个对象键对应一个。我的数据示例:

    { field: ['data', 'client', 'name'] },
    { field: ['data', 'client', 'contact_name'] },
    { field: ['data', 'client', 'email'] },
    { field: ['data', 'client', 'phone'] },
    

    这有点令人困惑,因为我的初学者大脑预计定义“客户端”字段会简单地返回整个对象,如下所示:

    { field: ['data', 'client'] },

    文档中关于这个的唯一部分是这句话:The field ["data", "address", "street"] refers to the street field contained in an address object within the document’s data object.

    这是足够的信息,但也许它应该有自己的部分,有一个更长的例子?简单的句子当然可以,但是有一个名为“将对象添加到字段”之类的小节,这会使其更加清晰。

    希望我的困惑会有所帮助。到目前为止喜欢 FaunaDB,继续努力:)

    【讨论】:

    • 动物索引不能存储对象,只能存储标量值或标量值数组。虽然我们确实在几个地方提到了这一点,但我们可以更好地指出这一特定限制。感谢您的建议!我已经提交了一个文档问题以添加该标注。
    【解决方案2】:
    1. 您没有向我们确切展示您所做的工作,因此这里有一个示例,说明使用您按原样创建的索引对布尔值进行过滤确实有效:

      > CreateCollection({ name: "orders" })
      {
        ref: Collection("orders"),
        ts: 1618350087320000,
        history_days: 30,
        name: 'orders'
      }
      > Create(Collection("orders"), { data: {
          unique_id: 1,
          client: "me",
          material: "stone",
          date: Now(),
          status: true
      }})
      {
        ref: Ref(Collection("orders"), "295794155241603584"),
        ts: 1618350138800000,
        data: {
          unique_id: 1,
          client: 'me',
          material: 'stone',
          date: Time("2021-04-13T21:42:18.784Z"),
          status: true
        }
      }
      > Create(Collection("orders"), { data: {
        unique_id: 2,
        client: "you",
        material: "muslin",
        date: Now(),
        status: false
      }})
      {
        ref: Ref(Collection("orders"), "295794180038328832"),
        ts: 1618350162440000,
        data: {
          unique_id: 2,
          client: 'you',
          material: 'muslin',
          date: Time("2021-04-13T21:42:42.437Z"),
          status: false
        }
      }
      > CreateIndex({
        name: "orders_all_by_open_asc",
        unique: false,
        serialized: true,
        source: Collection("orders"),
        terms: [{ field: ["data", "status"] }],
        values: [
          { field: ["data", "unique_id"] },
          { field: ["data", "client"] },
          { field: ["data", "material"] },
          { field: ["data", "date"] }
        ]
      })
      {
        ref: Index("orders_all_by_open_asc"),
        ts: 1618350185940000,
        active: true,
        serialized: true,
        name: 'orders_all_by_open_asc',
        unique: false,
        source: Collection("orders"),
        terms: [ { field: [ 'data', 'status' ] } ],
        values: [
          { field: [ 'data', 'unique_id' ] },
          { field: [ 'data', 'client' ] },
          { field: [ 'data', 'material' ] },
          { field: [ 'data', 'date' ] }
        ],
        partitions: 1
      }
      > Paginate(Match(Index("orders_all_by_open_asc"), true))
      { data: [ [ 1, 'me', 'stone', Time("2021-04-13T21:42:18.784Z") ] ] }
      > Paginate(Match(Index("orders_all_by_open_asc"), false))
      { data: [ [ 2, 'you', 'muslin', Time("2021-04-13T21:42:42.437Z") ] ] }
      
    2. 这有点多,但你可以编写任何你喜欢的返回格式:

      > Map(
        Paginate(Match(Index("orders_all_by_open_asc"), false)),
        Lambda(
          ["unique_id", "client", "material", "date"],
          {
            unique_id: Var("unique_id"),
            client: Var("client"),
            material: Var("material"),
            date: Var("date"),
          }
        )
      )
      {
        data: [
          {
            unique_id: 2,
            client: 'you',
            material: 'muslin',
            date: Time("2021-04-13T21:42:42.437Z")
          }
        ]
      }
      

      它仍然是一个结果数组,但每个结果现在都是一个具有适当字段名称的对象。

    【讨论】:

    • Annnnnd 我忘了在我的查询中包含 Paginate!这就是为什么它不起作用。我只是在做Match(Index ...不会再犯那个错误了:)
    • 感谢您提供 Lambda 示例,我正努力思考它并知道 Lambda 可能会解决这个问题,但很难真正编写代码。这在 FaunaDB 文档中会很好,不是吗?他们的 Lambda 示例有点小。
    • (如果您想查看,请参考此页面)docs.fauna.com/fauna/current/api/fql/functions/…
    • 在文档的其他地方有返回对象的例子,但你是对的,没有一个 Lamda 例子证明了这种能力。我已经提交了一个问题来添加这样一个例子。
    • 如果您对其他示例有建议,请告诉我!
    【解决方案3】:

    对 FQL 不太熟悉,但对 SQL 语言有点熟悉。本质上,数据库语言通常将您的所有值视为字符串,直到它们不再需要为止。相反,您的查询应该使用 FQL 所期望的字符串定义。我相信在您的情况下它应该是 OPEN 或 CLOSED 。您可以简单地在 java 中使用 if 语句来确定是搜索“OPEN”还是“CLOSED”。

    要回答您的第二个问题,我不知道 FQL,但如果这是返回的内容,那么您使用 lamda 的方法似乎没问题。除了希望将来能以不同的方式以 API 形式获取条目之外,您对此无能为力。归根结底,这种情况下的 O(n) 操作还算不错,只需要返回一百左右的订单应该不是世界上最痛苦的事情。

    如果你真的很担心这个,你可以把请求分成几部分,所以你只返回前 100 个,然后当前端想要下一组时,你发送下一个 100。你也可以缓存结果来制作从前端的角度来看它非常快。

    【讨论】:

    • 是的,我想我会忘记布尔值,只为我的 WHERE(在 FQL,术语中)子句使用一个字符串。知道我是否可以通过布尔搜索仍然很高兴,但是现在我假设我不能。对于第二个问题,我确实可以摆脱更多的读取操作,但我希望对 FaunaDB 索引有更多的了解可以帮助我在未来编写更好的查询,我也很好奇其他人是如何使用的使用 FaunaDB 建立索引并解决这个问题 :)
    猜你喜欢
    • 2014-03-30
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    相关资源
    最近更新 更多