索引:按布尔值搜索?

Indexes: Search by Boolean?

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

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

我的目标是 search/filter 根据订单的状态,打开或关闭(布尔值 true/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"] }
  ]
}

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

我有两个问题:

  1. 当我使用 Javascript 驱动程序传递 TRUE OR FALSE 时,没有任何内容被 returned :( 是否可以完全通过布尔值搜索,或者只能通过 String/Number 搜索?

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

Match(Index("orders_all_by_open_asc"), true)

不幸的是,return什么都没有。我可能做错了。

  1. 第二个(稍微不相关的)问题。当我创建一个索引并指定一堆值时,数据 returned 似乎是数组格式,只有值,没有字段。一个例子:
[
  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..

在使用索引值时,是否有任何方法可以获取字段和值,或者它总是return一个数组(而不是一个对象)?

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

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

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

这工作得很好,但不幸的是,它还对每个 returned 文档执行一个 Get 请求,这看起来效率很低。

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

提前致谢!!索引很好但很难掌握,所以任何见解都将不胜感激。

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

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

如果你真的担心这个,你可以把请求分成几个部分,这样你就 return 只发送前 100 个,然后当前端需要下一组时,你发送下一个 100 个。你可以也缓存结果以使其从前端的角度来看非常快。

  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. 工作有点多,但您可以编写任何您喜欢的 return 格式:

    > 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")
        }
      ]
    }
    

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

另一个建议,也许我错了,没能搜索到文档,但无论如何我都会 post 以防万一它有帮助。

我的索引无法 return 个对象,这里的示例数据是 client 字段:

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

此处,client 字段 return 被设为 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'] },

这有点令人困惑,因为我的初学者大脑期望定义 'client' 字段会简单地 return 整个对象,如下所示:

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

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

这些信息已经足够了,但也许它应该单独一节,并提供更长的示例?简单的句子当然有效,但是有一个叫做 'Adding Objects to Fields' 之类的小节,这会让它变得格外清晰。

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