如何在Firestore中为不同字段组合“或”查询

时间:2020-08-12 23:54:47

标签: javascript google-cloud-firestore

我有一个像这样的“狗”收藏品:

  var searchTerm = "Chiwawa";

  var query = dogsCollection
    .where("color", "in", ["Yellow", "Black", "White"])
    .where("size", "in", ["Medium", "Small"])
    .orderBy("name")
    .startAt(searchTerm)
    .endAt(searchTerm + "\uf8ff")
    .limit(2);

我想按名称,颜色和大小搜索狗,我的查询如下:

static async Task Main(string[] args)
        {
            // Load from the default kubeconfig on the machine.
            var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();

            // Use the config object to create a client.
            var client = new Kubernetes(config);


            try
            {

                var podlistResp = await client.ListNamespacedPodWithHttpMessagesAsync(Namespace, watch: true);
                using (podlistResp.Watch<V1Pod, V1PodList>(async (type, item) =>
                {
                    Console.WriteLine(type);
                    Console.WriteLine("==on watch event==");
                    var message = $"Namespace: {Namespace} Pod: {item.Metadata.Name} Type: {type}  Phase:{item.Status.Phase}";
                    var remessage = $"Namespace: {Namespace} Pod: {item.Metadata.Name} Type: {type} back to Phase:{item.Status.Phase}";
                    Console.WriteLine(message);
                    if (!item.Status.Phase.Equals("Running") && !item.Status.Phase.Equals("Succeeded"))
                    {   Console.WriteLine("==on watch event==");
                        await Notify(message);
                        Console.WriteLine("==on watch event==");
                    }
                    if ( type== WatchEventType.Modified && item.Status.Phase.Equals("Running") )
                    {   Console.WriteLine("==on watch event==");
                        await Notify(remessage);
                        Console.WriteLine("==on watch event==");
                    }
                }))
                {
                    
                    Console.WriteLine("press ctrl + c to stop watching");

                    var ctrlc = new ManualResetEventSlim(false);
                    Console.CancelKeyPress += (sender, eventArgs) => ctrlc.Set();
                    ctrlc.Wait();
                }
            }
            
            catch (System.Exception ex)
            {
                Console.Error.WriteLine($"An error happened Message: {ex.Message}", ex);
            }
        }

        private static async Task Notify(string message)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("https://outlook.office.com");
                var body = new { text = message };
                var content = new StringContent(JsonConvert.SerializeObject(body));
                var result = await client.PostAsync("https://outlook.office.com/webhook/xxxx/IncomingWebhook/xxx", content);
                result.EnsureSuccessStatusCode();
            }
        }

但是由于firestore的限制,我将无法使用“ in”两次,因此必须分别使用按颜色和大小进行查询并将结果组合在一起(使用Promise),但这无法解决问题分页。请给我解决方案吗?

2 个答案:

答案 0 :(得分:0)

这确实可能是一个问题。我建议您查看documentation中有关Firestore中的分页的信息(如果您尚未这样做的话)。

当我查看您的用例时,您似乎可以将“大小”转换为数字值(小:1,中:2,大:3),并将其与使用标准关系的Compound查询一起使用运算符。

因此而不是:

.where("size", "in", ["Medium", "Small"])

您可以使用:

.where("size", "<", 3)

这并不完美,但是可以与where +“ in”方法结合使用。

答案 1 :(得分:0)

您唯一可行的解​​决方法是存储一个字段,其中包含您要一起查询的其他两个字段的复合数据。例如,您可能有一个名为“ size-color”的数组字段,其中包含大小和颜色的每种可能组合的级联值,这对于给定的狗是正确的。

因此,如果您的狗是“ Small”和“ Yellow”,则“ size-color”字段的值为“ Small-Yellow”。然后,您可以使用以下过滤器查询该文档:

.where("size-color", "in", ["Small-Yellow"])

然后,您可以添加更多组合:

.where("size-color", "in", ["Small-Yellow", "Small-Black", "Small-White"])

问题在于,一个in查询只能包含10个项目,因此您会在一段时间后看到这种情况。

Firestore不太适合此类查询。如果您想要更灵活的查询,则确实应该考虑放弃分页。