1

以下是 couchbase 中的示例记录

{
  a: "iama",
  b: {
    c: "iamc",
    d: "iamd",
  },
  f: "iamf"
  // ... other properties we don't care about

}

{
  a: "iama",
  b: {
    c: "iamc",
    d: "iamd"
  },
  f: "iamnotf"
  // ... other properties we don't care about

}

我想找到b匹配整个对象的记录,但不确定 b 包含什么。

我正在使用 ottomanjs,这是我的尝试。我觉得很丑

    const arr = [];
    Object.keys(b).forEach((key) => {
      const k = `b.${key}`;
      arr.push({ [k]: b[key] });
    });

    model.find({ $and: arr });

所以在上面的例子中,过滤器看起来像这样:

{
  "$and": [
    {
      "b.c": "iamc"
    },
    {
      "b.d": "iamd"
    }
  ]
}

它会将该过滤器转换为 n1ql 查询,如下所示:

SELECT * FROM `table` WHERE ( b.c="iamc" AND b.d="iamd") AND _type="model..."

这只是解决方案的一半,因为我假设 b 的每个属性都不是嵌套对象。但当然,我可以有一个递归函数来构造过滤器。

也许另一种方法是处理内存中的所有内容。利用JSON.stringify(b1) == JSON.stringfy(b2)_.isEqual(b1, b2)

我几乎可以肯定这不是最佳做法。有什么建议吗?或者只是另一种方法。


**其他信息

如果我希望所有记录都有一个唯一的 b 字段怎么办?我可以使用 b 的字符串化版本作为文档的键。所以当试图查找 b 时,我只是按文档 ID 搜索。不能用 Ottoman 做到这一点,但可以用 couchbase sdk

4

1 回答 1

1

只需执行 WHERE b1 = b2。它执行 Json 比较字段名称、值(包括值类型)、以防数组位置、递归嵌套信息。encode_josn() 是 stringfy。

下面的示例给出了一个文档与其他文档不匹配。

SELECT t 
FROM [{ "a": "iama", 
        "b":  { "c": "iamc", "d": "iamd" },
        "b1": { "c": "iamc", "d": "iamd" } }, 
      { "a": "iama", 
        "b":  { "c": "iamc", "d": "iamd" }, 
        "b1": { "c1": "iamc", "d": "iamd" } }
      ] AS t 
WHERE t.b = t.b1;

{
    "results": [
    {
        "t": {
            "a": "iama",
            "b": {
                "c": "iamc",
                "d": "iamd"
            },
            "b1": {
                "c": "iamc",
                "d": "iamd"
            }
        }
    }
    ]
}

https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/datatypes.html#collat​​ion

于 2021-09-24T12:54:48.060 回答