我正在使用家庭住址从数据库中获取经度和纬度值。

集合中每个文档的结构如下:

"Ext": string
"Lat": string
"Long": string
"Parish": string
"Postal": string
"Street": string
"Number": string


有几种不同的where()条件,所有条件都包裹在if语句中。

街道编号where()条件始终导致查询不返回任何匹配项,而所有其他where()的find均正确匹配。

我努力了:


注释掉街道编号where()条件
从数据库复制的硬编码值
在where()调用中使用parseInt()和toString()强制键入
将有关字符串的数据记录到控制台以检查键入,前导/后缀空格等。


function addressToCoords() {
  // returns an array of coordinates if successful, false otherwise

  const ADD = document.getElementById("address").value;
  let NUM;
  let STREET;
  if (ADD) {
    NUM = ADD.match(/^[0-9]+/)[0];
    STREET = ADD.replace(/^[0-9]+\s/, "");

    if (NUM === STREET) {
      console.log("NUM = STREET. regex split failed");
      STREET = null;
      return false;
    }
  }

  const CTY = document.getElementById('parish').value;
  const POS = document.getElementById('postalCode').value.replace(/\s/, "");

  let coords = [0.0, 0.0];
  let query = f.addresses;

  if (CTY) { console.log("CTY: ", CTY); query = query.where("Parish", "==", CTY); }

  if (STREET) { console.log("STREET: ", STREET); query = query.where("Street", "==", STREET); }

  if (POS) { console.log("POS: ", POS); query = query.where("Postal", "==", POS); }

  // -FIXME- doesn't match
  if (NUM) {
    // Usual test case outputs:
    //           NUM:     1          string              1
    console.log("NUM: ", NUM, " ", typeof(NUM), " ", NUM.length);
    query = query.where("Number", "==", NUM);
  }

  query.limit(5)
    .get()
    .then(querySnapshot => {
      if (!querySnapshot.empty) {
        querySnapshot.docs.forEach (ele => {
          console.log("doc found!: ", ele.data());
        });
        coords[0] = querySnapshot.docs[0].Lat;
        coords[1] = querySnapshot.docs[0].Long;
      } else {
        console.log("no doc found!");
      }
  }).catch(function(error) {
    console.log(error);
  });

  document.getElementById("Latitude").value = coords[0];
  document.getElementById('Longitude').value = coords[1];

  return coords;
}


任何见解均表示赞赏。

编辑:目前,我还在Firebase支持下往返,显然我的代码成功查询了rep构建的示例数据库并正常运行。

这似乎在数据库结构上留下了某种问题,但是...


我不是在查询其他集合
所有文档具有相同类型的相同字段
我所做的测试似乎不允许查询中出现类型不匹配的可能性


这可能是我的无知,但问题似乎很奇怪。

最佳答案

Firebase支持非常有帮助。这个答案要归功于支持代表的解决方案。

谢谢卡洛斯!

因此,事实证明我的代码是正确的,我的数据存在一个非常细微的问题。

我已经以csv格式从另一个数据库下载了该数据库中的数据,并使用Excel验证了内容,并在某个时候保存了该数据。作为Excel的Excel决定,任何好的UTF-8编码的csv文件都必须以字节顺序标记开头。

对于那些不知道(例如我不知道)的人,字节序标记是unicode字符集中的不可见字符(零宽度)。它们会在某些文本编辑器中显示为怪异的问号符号,但通常根本不会显示。

一些further reading

具体来说,BOM用于指定字节字符串的endianness,以便可以正确解释它们。

BOM最终成为数据库Number字段名称中的第一个字符,因为那是csv文件中指定的第一列,而且,与直觉相反,这不是匹配的值,而是该字段名称。

有一些迹象表明我缺乏认识的背景:


Firestore控制台将“ Number”字段放在按字典顺序排序的字段列表的底部
数字是Firestore控制台中唯一用引号引起来的字段名称


解决方案是:

更新集合中的每个条目(因为csv列名称成为csv到json转换中的属性名称,然后是我上载时的firestore字段名称),

要么

完全删除集合,并使用某种查找和替换工具(VS Code的搜索完成了此工作),将所有BOM替换为空字符串(只需在VS Code搜索中未指定替换值,然后点击“全部替换”即可) 。

如果数据还有零宽度(或其他不受欢迎的)字符的其他问题,则可以使用白名单过滤工具将其过滤掉。将黑名单从理论上讲是可行的,但是如果使用的字符集与unicode一样大,那么除非您只过滤掉零宽度字符,否则它将不切实际。

感谢所有看过的人!

10-05 20:30
查看更多